From 4448410c3ea263e1ac2cc10d9caacbc571645e42 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 1 Nov 2024 14:02:27 -0500 Subject: [PATCH 01/38] Partial implementation --- .circleci/config.yml | 2 +- .../homebrew/editor/snippetbar/snippetbar.jsx | 4 ++ client/homebrew/pages/editPage/editPage.jsx | 2 + package.json | 4 +- server/homebrew.api.js | 6 ++ shared/helpers.js | 60 +++++++++++++++++++ 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f18f84943..abd8faacc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,7 @@ orbs: jobs: build: docker: - - image: cimg/node:20.17.0 + - image: cimg/node:20.18.0 - image: mongo:4.4 working_directory: ~/homebrewery diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 50237b914..1f786fd93 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -6,6 +6,7 @@ const _ = require('lodash'); const cx = require('classnames'); import { loadHistory } from '../../utils/versionHistory.js'; +import { brewSnippetsToJSON } from '../../../../shared/helpers.js'; //Import all themes const ThemeSnippets = {}; @@ -114,6 +115,9 @@ const Snippetbar = createClass({ oldSnippets = _.keyBy(compiledSnippets, 'groupName'); } + const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props.snippetsBundle); + compiledSnippets.push(userSnippetsasJSON); + return compiledSnippets; }, diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 744e187a6..a98b16717 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -61,6 +61,7 @@ const EditPage = createClass({ currentEditorCursorPageNum : 1, currentBrewRendererPageNum : 1, displayLockMessage : this.props.brew.lock || false, + snippetsBundle : {}, themeBundle : {} }; }, @@ -440,6 +441,7 @@ const EditPage = createClass({ reportError={this.errorReported} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} + snippets={this.props.snippets} snippetBundle={this.state.themeBundle.snippets} updateBrew={this.updateBrew} onCursorPageChange={this.handleEditorCursorPageChange} diff --git a/package.json b/package.json index 94d0122ab..3fe3ce5a6 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "description": "Create authentic looking D&D homebrews using only markdown", "version": "3.16.0", "engines": { - "npm": "^10.2.x", - "node": "^20.17.x" + "npm": "^10.8.x", + "node": "^20.18.x" }, "repository": { "type": "git", diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 213b341ca..2abbf9485 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -170,6 +170,12 @@ const api = { `\`\`\`\n\n` + `${text}`; } + if(brew.snippets !== undefined) { + text = `\`\`\`snippets\n` + + `${brew.snippets || ''}\n` + + `\`\`\`\n\n` + + `${text}`; + } const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']); text = `\`\`\`metadata\n` + `${yaml.dump(metadata)}\n` + diff --git a/shared/helpers.js b/shared/helpers.js index ac684b06f..e75dcdb28 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -1,6 +1,65 @@ const _ = require('lodash'); const yaml = require('js-yaml'); const request = require('../client/homebrew/utils/request-middleware.js'); +const dedent = require('dedent'); + +// Convert the templates from a brew to a Snippets Structure. +const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ + const textSplit = /^\\page/gm; + const mpAsSnippets = []; + // Snippets from Themes first. + if(themeBundleSnippets) { + for (let themes of themeBundleSnippets) { + const userSnippets = []; + for (let snips of themes.snippets.split(textSplit)) { + const name = snips.split('\n')[0]; + if(name.length != 0) { + userSnippets.push({ + name : name, + icon : '', + gen : snips.split('\n').slice(0), + }); + } + } + if(userSnippets.length > 0) { + mpAsSnippets.push({ + name : themes.name, + icon : '', + gen : '', + subsnippets : userSnippets + }); + } + } + } + // Local Snippets + if(userBrewSnippets) { + const userSnippets = []; + for (let snips of userBrewSnippets.split(textSplit)) { + let name = mp.split('\n')[0]; + if(name.length != 0) { + userSnippets.push({ + name : name, + icon : '', + gen : snips.split('\n').slice(0), + }); + } + } + if(userSnippets.length) { + mpAsSnippets.push({ + name : menuTitle, + icon : '', + subsnippets : userSnippets + }); + } + } + + return { + groupName : 'Brew Snippets', + icon : 'fas fa-th-list', + view : 'text', + snippets : mpAsSnippets + }; +}; const splitTextStyleAndMetadata = (brew)=>{ brew.text = brew.text.replaceAll('\r\n', '\n'); @@ -55,4 +114,5 @@ module.exports = { splitTextStyleAndMetadata, printCurrentBrew, fetchThemeBundle, + brewSnippetsToJSON }; From 7cd82ffc4edaf2ee47b38cb6ca4298957483ed47 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 2 Nov 2024 17:37:43 -0500 Subject: [PATCH 02/38] WOrking snippets insertion from local. --- shared/helpers.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index e75dcdb28..b84cb0332 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -35,12 +35,12 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ if(userBrewSnippets) { const userSnippets = []; for (let snips of userBrewSnippets.split(textSplit)) { - let name = mp.split('\n')[0]; + let name = snips.split('\n')[0]; if(name.length != 0) { userSnippets.push({ - name : name, + name : name.slice('\snippet '.length), icon : '', - gen : snips.split('\n').slice(0), + gen : snips.slice(name.length + 1), }); } } @@ -70,16 +70,19 @@ const splitTextStyleAndMetadata = (brew)=>{ Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); brew.text = brew.text.slice(index + 5); } - if(brew.text.startsWith('```css')) { - const index = brew.text.indexOf('```\n\n'); - brew.style = brew.text.slice(7, index - 1); - brew.text = brew.text.slice(index + 5); - } if(brew.text.startsWith('```snippets')) { const index = brew.text.indexOf('```\n\n'); brew.snippets = brew.text.slice(11, index - 1); brew.text = brew.text.slice(index + 5); } + if(brew.text.startsWith('```css')) { + const index = brew.text.indexOf('```\n\n'); + brew.style = brew.text.slice(7, index - 1); + brew.text = brew.text.slice(index + 5); + } + // if(!brew?.snippets) { + brew.snippets = `\\snippet Example\nI am an example user snippet\n`; + // } }; const printCurrentBrew = ()=>{ From 4f240bf1100c46fca948b00899d71a2db2bb4205 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 2 Nov 2024 22:30:18 -0500 Subject: [PATCH 03/38] WIP --- client/homebrew/editor/editor.jsx | 2 +- .../homebrew/editor/snippetbar/snippetbar.jsx | 21 ++++++++++++------- server/homebrew.api.js | 4 +--- server/homebrew.api.spec.js | 2 -- shared/helpers.js | 7 +++++-- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 9fef72cbb..27737fcba 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -499,7 +499,7 @@ const Editor = createClass({ historySize={this.historySize()} currentEditorTheme={this.state.editorTheme} updateEditorTheme={this.updateEditorTheme} - snippetBundle={this.props.snippetBundle} + themeBundle={this.props.themeBundle} cursorPos={this.codeEditor.current?.getCursorPosition() || {}} updateBrew={this.props.updateBrew} /> diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 1f786fd93..111b4fd38 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -41,7 +41,6 @@ const Snippetbar = createClass({ unfoldCode : ()=>{}, updateEditorTheme : ()=>{}, cursorPos : {}, - snippetBundle : [], updateBrew : ()=>{} }; }, @@ -102,20 +101,26 @@ const Snippetbar = createClass({ }, compileSnippets : function() { + console.log('compileSnippets'); let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); - for (let snippets of this.props.snippetBundle) { - if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name - snippets = ThemeSnippets[snippets]; + console.log(this.props.themesBundle); - const newSnippets = _.keyBy(_.cloneDeep(snippets), 'groupName'); - compiledSnippets = _.values(_.mergeWith(oldSnippets, newSnippets, this.mergeCustomizer)); + if( this.props.themesBundle) { + for (let snippets of this.props?.themesBundle?.snippets) { + if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name + snippets = ThemeSnippets[snippets]; - oldSnippets = _.keyBy(compiledSnippets, 'groupName'); + const newSnippets = _.keyBy(_.cloneDeep(snippets), 'groupName'); + compiledSnippets = _.values(_.mergeWith(oldSnippets, newSnippets, this.mergeCustomizer)); + + oldSnippets = _.keyBy(compiledSnippets, 'groupName'); + } } - const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props.snippetsBundle); + console.log(this.props.themesBundle); + const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props?.themesBundle?.snippets); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 2abbf9485..685415c14 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -296,7 +296,7 @@ const api = { splitTextStyleAndMetadata(currentTheme); // If there is anything in the snippets or style members, append them to the appropriate array - if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); + if(currentTheme?.snippets) completeSnippets.push({ name: currentTheme.title, snippets: currentTheme.snippets }); if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`); req.params.id = currentTheme.theme; @@ -304,9 +304,7 @@ const api = { } //=== Static Themes ===// else { - const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; - completeSnippets.push(localSnippets); completeStyles.push(`/* From Theme ${req.params.id} */\n\n${localStyle}`); req.params.id = Themes[req.params.renderer][req.params.id].baseTheme; diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index a1222cb57..3c86e4208 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -627,8 +627,6 @@ brew`); `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");` ], snippets : [ - 'V3_Blank', - 'V3_5ePHB' ] }); }); diff --git a/shared/helpers.js b/shared/helpers.js index b84cb0332..d5a4512a6 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -8,9 +8,12 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ const textSplit = /^\\page/gm; const mpAsSnippets = []; // Snippets from Themes first. + //console.log(themeBundleSnippets); if(themeBundleSnippets) { + console.log('Looping!'); for (let themes of themeBundleSnippets) { const userSnippets = []; + console.log(themes); for (let snips of themes.snippets.split(textSplit)) { const name = snips.split('\n')[0]; if(name.length != 0) { @@ -80,9 +83,9 @@ const splitTextStyleAndMetadata = (brew)=>{ brew.style = brew.text.slice(7, index - 1); brew.text = brew.text.slice(index + 5); } - // if(!brew?.snippets) { + if(!brew?.snippets) { brew.snippets = `\\snippet Example\nI am an example user snippet\n`; - // } + } }; const printCurrentBrew = ()=>{ From b9b3d284cf3d89a62b671789047cd7c0ea0defde Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 3 Nov 2024 11:14:31 -0600 Subject: [PATCH 04/38] WOrking snippet editor - menu population regression --- client/homebrew/editor/editor.jsx | 19 +++++++++++- .../homebrew/editor/snippetbar/snippetbar.jsx | 18 +++++++----- .../editor/snippetbar/snippetbar.less | 3 ++ client/homebrew/pages/editPage/editPage.jsx | 17 +++++++++-- server/homebrew.api.js | 2 ++ shared/helpers.js | 29 +++++++++---------- 6 files changed, 61 insertions(+), 27 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 27737fcba..dedfeaebb 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -21,6 +21,7 @@ const DEFAULT_STYLE_TEXT = dedent` color: black; }`; +const DEFAULT_SNIPPET_TEXT = ``; let isJumping = false; const Editor = createClass({ @@ -35,6 +36,7 @@ const Editor = createClass({ onTextChange : ()=>{}, onStyleChange : ()=>{}, onMetaChange : ()=>{}, + onSnipChange : ()=>{}, reportError : ()=>{}, onCursorPageChange : ()=>{}, @@ -51,7 +53,7 @@ const Editor = createClass({ getInitialState : function() { return { editorTheme : this.props.editorTheme, - view : 'text' //'text', 'style', 'meta' + view : 'text' //'text', 'style', 'meta', 'snip' }; }, @@ -61,6 +63,7 @@ const Editor = createClass({ isText : function() {return this.state.view == 'text';}, isStyle : function() {return this.state.view == 'style';}, isMeta : function() {return this.state.view == 'meta';}, + isSnip : function() {return this.state.view == 'snip';}, componentDidMount : function() { @@ -459,6 +462,20 @@ const Editor = createClass({ userThemes={this.props.userThemes}/> ; } + + if(this.isSnip()){ + return <> + + ; + } }, redo : function(){ diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 111b4fd38..bb932c0fe 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -41,6 +41,7 @@ const Snippetbar = createClass({ unfoldCode : ()=>{}, updateEditorTheme : ()=>{}, cursorPos : {}, + themeBundle : [], updateBrew : ()=>{} }; }, @@ -64,7 +65,7 @@ const Snippetbar = createClass({ }, componentDidUpdate : async function(prevProps, prevState) { - if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme || prevProps.snippetBundle != this.props.snippetBundle) { + if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme || prevProps.themeBundle != this.props.themeBundle) { this.setState({ snippets : this.compileSnippets() }); @@ -101,15 +102,12 @@ const Snippetbar = createClass({ }, compileSnippets : function() { - console.log('compileSnippets'); let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); - console.log(this.props.themesBundle); - - if( this.props.themesBundle) { - for (let snippets of this.props?.themesBundle?.snippets) { + if(this.props.themeBundle.snippets) { + for (let snippets of this.props.themeBundle.snippets) { if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name snippets = ThemeSnippets[snippets]; @@ -119,8 +117,8 @@ const Snippetbar = createClass({ oldSnippets = _.keyBy(compiledSnippets, 'groupName'); } } - console.log(this.props.themesBundle); - const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props?.themesBundle?.snippets); + + const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props.themeBundle.snippets); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; @@ -266,6 +264,10 @@ const Snippetbar = createClass({ onClick={()=>this.props.onViewChange('meta')}> +
this.props.onViewChange('snip')}> + +
; diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 319cd0cad..a7202c428 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -48,6 +48,9 @@ &.meta { .tooltipLeft('Properties'); } + &.snip { + .tooltipLeft('Snippets'); + } &.undo { .tooltipLeft('Undo'); font-size : 0.75em; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index a98b16717..df840bc48 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -61,7 +61,6 @@ const EditPage = createClass({ currentEditorCursorPageNum : 1, currentBrewRendererPageNum : 1, displayLockMessage : this.props.brew.lock || false, - snippetsBundle : {}, themeBundle : {} }; }, @@ -143,6 +142,19 @@ const EditPage = createClass({ }), ()=>{if(this.state.autoSave) this.trySave();}); }, + handleSnipChange : function(snippet){ + console.log('Snip Change!'); + //If there are errors, run the validator on every change to give quick feedback + let htmlErrors = this.state.htmlErrors; + if(htmlErrors.length) htmlErrors = Markdown.validate(snippet); + + this.setState((prevState)=>({ + brew : { ...prevState.brew, snippets: snippet }, + isPending : true, + htmlErrors : htmlErrors, + }), ()=>{if(this.state.autoSave) this.trySave();}); + }, + handleStyleChange : function(style){ this.setState((prevState)=>({ brew : { ...prevState.brew, style: style }, @@ -438,11 +450,12 @@ const EditPage = createClass({ onTextChange={this.handleTextChange} onStyleChange={this.handleStyleChange} onMetaChange={this.handleMetaChange} + onSnipChange={this.handleSnipChange} reportError={this.errorReported} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} snippets={this.props.snippets} - snippetBundle={this.state.themeBundle.snippets} + themeBundle={this.state.themeBundle} updateBrew={this.updateBrew} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 685415c14..9c4f55ef7 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -304,7 +304,9 @@ const api = { } //=== Static Themes ===// else { + const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; + completeSnippets.push(localSnippets); completeStyles.push(`/* From Theme ${req.params.id} */\n\n${localStyle}`); req.params.id = Themes[req.params.renderer][req.params.id].baseTheme; diff --git a/shared/helpers.js b/shared/helpers.js index d5a4512a6..27c372dd7 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -8,29 +8,26 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ const textSplit = /^\\page/gm; const mpAsSnippets = []; // Snippets from Themes first. - //console.log(themeBundleSnippets); if(themeBundleSnippets) { - console.log('Looping!'); for (let themes of themeBundleSnippets) { - const userSnippets = []; - console.log(themes); - for (let snips of themes.snippets.split(textSplit)) { - const name = snips.split('\n')[0]; + if(typeof themes !== 'string') { + const userSnippets = []; + const name = themes.snippets.split('\n')[0]; if(name.length != 0) { userSnippets.push({ - name : name, + name : name.slice('\snippets '.length), icon : '', - gen : snips.split('\n').slice(0), + gen : themes.snippets.slice(name.length + 1), + }); + } + if(userSnippets.length > 0) { + mpAsSnippets.push({ + name : themes.name, + icon : '', + gen : '', + subsnippets : userSnippets }); } - } - if(userSnippets.length > 0) { - mpAsSnippets.push({ - name : themes.name, - icon : '', - gen : '', - subsnippets : userSnippets - }); } } } From 7f7f3557b36e29575e3703137445149d015f49fd Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 3 Nov 2024 12:30:14 -0600 Subject: [PATCH 05/38] Mostly working. Needs tweakages. Presentable --- client/homebrew/editor/editor.jsx | 2 +- .../homebrew/editor/snippetbar/snippetbar.jsx | 5 +++- client/homebrew/pages/editPage/editPage.jsx | 1 - shared/helpers.js | 24 ++++++++++--------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index dedfeaebb..6c74bfdf7 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -158,7 +158,7 @@ const Editor = createClass({ highlightCustomMarkdown : function(){ if(!this.codeEditor.current) return; - if(this.state.view === 'text') { + if(this.state.view === 'text') { const codeMirror = this.codeEditor.current.codeMirror; codeMirror.operation(()=>{ // Batch CodeMirror styling diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index bb932c0fe..066711c41 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -65,7 +65,10 @@ const Snippetbar = createClass({ }, componentDidUpdate : async function(prevProps, prevState) { - if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme || prevProps.themeBundle != this.props.themeBundle) { + if(prevProps.renderer != this.props.renderer || + prevProps.theme != this.props.theme || + prevProps.themeBundle != this.props.themeBundle || + prevProps.brew.snippets != this.props.brew.snippets) { this.setState({ snippets : this.compileSnippets() }); diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index df840bc48..be5af729b 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -143,7 +143,6 @@ const EditPage = createClass({ }, handleSnipChange : function(snippet){ - console.log('Snip Change!'); //If there are errors, run the validator on every change to give quick feedback let htmlErrors = this.state.htmlErrors; if(htmlErrors.length) htmlErrors = Markdown.validate(snippet); diff --git a/shared/helpers.js b/shared/helpers.js index 27c372dd7..750f533cd 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -5,20 +5,22 @@ const dedent = require('dedent'); // Convert the templates from a brew to a Snippets Structure. const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ - const textSplit = /^\\page/gm; + const textSplit = /^\\snippet /gm; const mpAsSnippets = []; // Snippets from Themes first. if(themeBundleSnippets) { for (let themes of themeBundleSnippets) { if(typeof themes !== 'string') { const userSnippets = []; - const name = themes.snippets.split('\n')[0]; - if(name.length != 0) { - userSnippets.push({ - name : name.slice('\snippets '.length), - icon : '', - gen : themes.snippets.slice(name.length + 1), - }); + for (let snips of themes.snippets.trim().split(textSplit)) { + const name = snips.trim().split('\n')[0]; + if(name.length != 0) { + userSnippets.push({ + name : name.slice('\snippets'.length), + icon : '', + gen : snips.slice(name.length + 1), + }); + } } if(userSnippets.length > 0) { mpAsSnippets.push({ @@ -34,11 +36,11 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ // Local Snippets if(userBrewSnippets) { const userSnippets = []; - for (let snips of userBrewSnippets.split(textSplit)) { + for (let snips of userBrewSnippets.trim().split(textSplit)) { let name = snips.split('\n')[0]; if(name.length != 0) { userSnippets.push({ - name : name.slice('\snippet '.length), + name : name, icon : '', gen : snips.slice(name.length + 1), }); @@ -72,7 +74,7 @@ const splitTextStyleAndMetadata = (brew)=>{ } if(brew.text.startsWith('```snippets')) { const index = brew.text.indexOf('```\n\n'); - brew.snippets = brew.text.slice(11, index - 1); + brew.snippets = brew.text.slice(12, index - 1); brew.text = brew.text.slice(index + 5); } if(brew.text.startsWith('```css')) { From f4e951623348728d243f5097e532b459a8cee638 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 3 Nov 2024 12:41:04 -0600 Subject: [PATCH 06/38] Remove testing helper --- shared/helpers.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index 750f533cd..8b94704bd 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -82,9 +82,6 @@ const splitTextStyleAndMetadata = (brew)=>{ brew.style = brew.text.slice(7, index - 1); brew.text = brew.text.slice(index + 5); } - if(!brew?.snippets) { - brew.snippets = `\\snippet Example\nI am an example user snippet\n`; - } }; const printCurrentBrew = ()=>{ From f43a155e6efad0e267ebfb0196d94546923062fc Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 3 Nov 2024 12:52:54 -0600 Subject: [PATCH 07/38] Fix Test --- server/homebrew.api.spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 3c86e4208..a1222cb57 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -627,6 +627,8 @@ brew`); `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");` ], snippets : [ + 'V3_Blank', + 'V3_5ePHB' ] }); }); From e0400c0425be5d00c3541fca64bda5f2ed43bf8f Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 12 Nov 2024 18:41:31 -0600 Subject: [PATCH 08/38] Snippets should go after existing tab sections --- shared/helpers.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index 8b94704bd..e603abaf0 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -72,16 +72,16 @@ const splitTextStyleAndMetadata = (brew)=>{ Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); brew.text = brew.text.slice(index + 5); } - if(brew.text.startsWith('```snippets')) { - const index = brew.text.indexOf('```\n\n'); - brew.snippets = brew.text.slice(12, index - 1); - brew.text = brew.text.slice(index + 5); - } if(brew.text.startsWith('```css')) { const index = brew.text.indexOf('```\n\n'); brew.style = brew.text.slice(7, index - 1); brew.text = brew.text.slice(index + 5); } + if(brew.text.startsWith('```snippets')) { + const index = brew.text.indexOf('```\n\n'); + brew.snippets = brew.text.slice(12, index - 1); + brew.text = brew.text.slice(index + 5); + } }; const printCurrentBrew = ()=>{ From f7561b78247ea98c85a5f65f0452bf578ef0890d Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 13 Nov 2024 20:53:04 -0600 Subject: [PATCH 09/38] Insert a CR --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index df7f41503..5206f4cbf 100644 --- a/README.md +++ b/README.md @@ -144,3 +144,4 @@ your contribution to the project, please join our [gitter chat][gitter-url]. [github-mark-duplicate-url]: https://docs.github.com/en/free-pro-team@latest/github/managing-your-work-on-github/about-duplicate-issues-and-pull-requests [github-pr-docs-url]: https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request [gitter-url]: https://gitter.im/naturalcrit/Lobby + From d541a70da54ee4f59f72255518cfe3380e6690ab Mon Sep 17 00:00:00 2001 From: David Bolack Date: Thu, 14 Nov 2024 06:54:36 -0600 Subject: [PATCH 10/38] Remove unneeded dedent --- shared/helpers.js | 1 - 1 file changed, 1 deletion(-) diff --git a/shared/helpers.js b/shared/helpers.js index e603abaf0..f5411f501 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -1,7 +1,6 @@ const _ = require('lodash'); const yaml = require('js-yaml'); const request = require('../client/homebrew/utils/request-middleware.js'); -const dedent = require('dedent'); // Convert the templates from a brew to a Snippets Structure. const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ From c5935ec262c3c59fd5db441df868655eb0232232 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 23 Nov 2024 01:57:07 -0600 Subject: [PATCH 11/38] Add Snippets to /new --- client/homebrew/pages/homePage/homePage.jsx | 3 ++- client/homebrew/pages/newPage/newPage.jsx | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 00d0c801d..0a598556a 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -108,7 +108,8 @@ const HomePage = createClass({ onTextChange={this.handleTextChange} renderer={this.state.brew.renderer} showEditButtons={false} - snippetBundle={this.state.themeBundle.snippets} + snippets={this.props.snippets} + themeBundle={this.state.themeBundle} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} currentEditorViewPageNum={this.state.currentEditorViewPageNum} diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index ee2c67d5f..ca31e03a5 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -141,6 +141,18 @@ const NewPage = createClass({ localStorage.setItem(STYLEKEY, style); }, + handleSnipChange : function(snippet){ + //If there are errors, run the validator on every change to give quick feedback + let htmlErrors = this.state.htmlErrors; + if(htmlErrors.length) htmlErrors = Markdown.validate(snippet); + + this.setState((prevState)=>({ + brew : { ...prevState.brew, snippets: snippet }, + isPending : true, + htmlErrors : htmlErrors, + }), ()=>{if(this.state.autoSave) this.trySave();}); + }, + handleMetaChange : function(metadata, field=undefined){ if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed fetchThemeBundle(this, metadata.renderer, metadata.theme); @@ -231,9 +243,11 @@ const NewPage = createClass({ onTextChange={this.handleTextChange} onStyleChange={this.handleStyleChange} onMetaChange={this.handleMetaChange} + onSnipChange={this.handleSnipChange} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} - snippetBundle={this.state.themeBundle.snippets} + snippets={this.props.snippets} + themeBundle={this.state.themeBundle} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} currentEditorViewPageNum={this.state.currentEditorViewPageNum} From b6e445c445355d60bc272fd20628fd0d7ab14cc3 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 24 Nov 2024 18:13:32 -0600 Subject: [PATCH 12/38] Convert storage of snippets in Brew to yaml by request. --- server/homebrew.api.js | 16 ++++++----- shared/helpers.js | 64 ++++++++++++++++++++++++++++-------------- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 42d4efca3..b0532e392 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -8,9 +8,11 @@ import Markdown from '../shared/naturalcrit/markdown.js'; import yaml from 'js-yaml'; import asyncHandler from 'express-async-handler'; import { nanoid } from 'nanoid'; -import { splitTextStyleAndMetadata } from '../shared/helpers.js'; +import { splitTextStyleAndMetadata, + brewSnippetsToJSON } from '../shared/helpers.js'; import checkClientVersion from './middleware/check-client-version.js'; + const router = express.Router(); import { DEFAULT_BREW, DEFAULT_BREW_LOAD } from './brewDefaults.js'; @@ -176,15 +178,15 @@ const api = { mergeBrewText : (brew)=>{ let text = brew.text; - if(brew.style !== undefined) { - text = `\`\`\`css\n` + - `${brew.style || ''}\n` + + if(brew.snippets !== undefined) { + text = `\`\`\`snippets\n` + + `${yaml.dump(brewSnippetsToJSON('brew_snippets', brew.snippets, null, false))}` + `\`\`\`\n\n` + `${text}`; } - if(brew.snippets !== undefined) { - text = `\`\`\`snippets\n` + - `${brew.snippets || ''}\n` + + if(brew.style !== undefined) { + text = `\`\`\`css\n` + + `${brew.style || ''}\n` + `\`\`\`\n\n` + `${text}`; } diff --git a/shared/helpers.js b/shared/helpers.js index be3c3331d..b6cbe2df8 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -3,7 +3,7 @@ import yaml from 'js-yaml'; import request from '../client/homebrew/utils/request-middleware.js'; // Convert the templates from a brew to a Snippets Structure. -const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ +const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=null, full=true)=>{ const textSplit = /^\\snippet /gm; const mpAsSnippets = []; // Snippets from Themes first. @@ -17,7 +17,7 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ userSnippets.push({ name : name.slice('\snippets'.length), icon : '', - gen : snips.slice(name.length + 1), + gen : snips.slice(name.length + 1).trim(), }); } } @@ -37,49 +37,71 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets)=>{ const userSnippets = []; for (let snips of userBrewSnippets.trim().split(textSplit)) { let name = snips.split('\n')[0]; + let justSnippet = snips.slice(name.length + 1); + if(justSnippet.slice(-1) === '\n') { + justSnippet = justSnippet.slice(0, -1); + } if(name.length != 0) { - userSnippets.push({ + const subSnip = { name : name, - icon : '', - gen : snips.slice(name.length + 1), - }); + gen : justSnippet, + }; + // if(full) subSnip.icon = ''; + userSnippets.push(subSnip); } } if(userSnippets.length) { mpAsSnippets.push({ name : menuTitle, - icon : '', + // icon : '', subsnippets : userSnippets }); } } - return { - groupName : 'Brew Snippets', - icon : 'fas fa-th-list', - view : 'text', - snippets : mpAsSnippets + const returnObj = { + snippets : mpAsSnippets }; + + if(full) { + returnObj.groupName = 'Brew Snippets'; + returnObj.icon = 'fas fa-th-list'; + returnObj.view = 'text'; + } + + return returnObj; +}; + +const yamlSnippetsToText = (yamlObj)=>{ + if(typeof yamlObj == 'string') return yamlObj; + + let snippetsText = ''; + for (let snippet of yamlObj.snippets) { + for (let subSnippet of snippet.subsnippets) { + snippetsText = `${snippetsText}\\snippet ${subSnippet.name}\n${subSnippet.gen || ''}\n`; + } + } + return snippetsText; }; const splitTextStyleAndMetadata = (brew)=>{ brew.text = brew.text.replaceAll('\r\n', '\n'); if(brew.text.startsWith('```metadata')) { - const index = brew.text.indexOf('```\n\n'); - const metadataSection = brew.text.slice(12, index - 1); + const index = brew.text.indexOf('\n```\n\n'); + const metadataSection = brew.text.slice(11, index - 1); const metadata = yaml.load(metadataSection); Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); - brew.text = brew.text.slice(index + 5); + brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```css')) { - const index = brew.text.indexOf('```\n\n'); - brew.style = brew.text.slice(7, index - 1); - brew.text = brew.text.slice(index + 5); + const index = brew.text.indexOf('\n```\n\n'); + brew.style = brew.text.slice(6, index - 1); + brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```snippets')) { - const index = brew.text.indexOf('```\n\n'); - brew.snippets = brew.text.slice(12, index - 1); - brew.text = brew.text.slice(index + 5); + const index = brew.text.indexOf('\n```\n\n'); + brew.snippets = yamlSnippetsToText(yaml.load(brew.text.slice(11, index - 1))).slice(0, -1); + brew.text = brew.text.slice(index + 6); } }; From 008b31e530166abbe7d9646af19b7a57747ef5cd Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 24 Nov 2024 18:58:50 -0600 Subject: [PATCH 13/38] Correct failing test. --- server/homebrew.api.spec.js | 2 +- shared/helpers.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 84ffc3052..2da940e40 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -908,7 +908,7 @@ brew`); }); describe('Get CSS', ()=>{ it('should return brew style content as CSS text', async ()=>{ - const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n````\n\n' }; + const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n```\n\n' }; const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); diff --git a/shared/helpers.js b/shared/helpers.js index b6cbe2df8..9b0b43084 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -88,19 +88,19 @@ const splitTextStyleAndMetadata = (brew)=>{ brew.text = brew.text.replaceAll('\r\n', '\n'); if(brew.text.startsWith('```metadata')) { const index = brew.text.indexOf('\n```\n\n'); - const metadataSection = brew.text.slice(11, index - 1); + const metadataSection = brew.text.slice(11, index + 1); const metadata = yaml.load(metadataSection); Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```css')) { const index = brew.text.indexOf('\n```\n\n'); - brew.style = brew.text.slice(6, index - 1); + brew.style = brew.text.slice(7, index + 1); brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```snippets')) { const index = brew.text.indexOf('\n```\n\n'); - brew.snippets = yamlSnippetsToText(yaml.load(brew.text.slice(11, index - 1))).slice(0, -1); + brew.snippets = yamlSnippetsToText(yaml.load(brew.text.slice(11, index + 1))).slice(0, -1); brew.text = brew.text.slice(index + 6); } }; From e763ae16313ff03713ea1f42f2c30af004d26929 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 24 Nov 2024 21:57:59 -0600 Subject: [PATCH 14/38] t shouldn't have been saved... --- package-lock.json | 39 ++++++++++++++++++++++++++++++++------- package.json | 2 +- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index b20286889..589e7b661 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "^1.0.10", + "marked-extended-tables": "file:../marked-extended-tables", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", @@ -71,6 +71,35 @@ "npm": "^10.8.x" } }, + "../marked-extended-tables": { + "version": "1.0.10", + "license": "MIT", + "devDependencies": { + "@babel/core": "^7.24.6", + "@babel/preset-env": "^7.25.4", + "@rollup/plugin-commonjs": "^26.0.1", + "@rollup/plugin-node-resolve": "^15.2.3", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/commit-analyzer": "^12.0.0", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^10.1.7", + "@semantic-release/npm": "^12.0.1", + "@semantic-release/release-notes-generator": "^13.0.0", + "babel-jest": "^29.5.0", + "eslint": "^8.57.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "jest-cli": "^29.7.0", + "marked": "^14.1.0", + "rollup": "^4.18.0", + "semantic-release": "^24.1.0" + }, + "peerDependencies": { + "marked": ">=3 <15" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -10543,12 +10572,8 @@ } }, "node_modules/marked-extended-tables": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.0.10.tgz", - "integrity": "sha512-zvRS0GPTkxq8UWawSDecd1Rxd2KD8crrmq2QALGDdrgkcgRNQzHlbnlujBGuXxdgDJg7f6UTv+JpcfejBpKdSg==", - "peerDependencies": { - "marked": ">=3 <15" - } + "resolved": "../marked-extended-tables", + "link": true }, "node_modules/marked-gfm-heading-id": { "version": "3.2.0", diff --git a/package.json b/package.json index 8755d0699..87390b48d 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "^1.0.10", + "marked-extended-tables": "file:../marked-extended-tables", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", From 74b4cb2afde0f97b02aa60781378670651bfe212 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 25 Nov 2024 13:59:24 -0600 Subject: [PATCH 15/38] Revert local error in package.json --- package-lock.json | 40 ++++++++-------------------------------- package.json | 2 +- 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 589e7b661..e5f637e46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "file:../marked-extended-tables", + "marked-extended-tables": "^1.0.10", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", @@ -71,35 +71,6 @@ "npm": "^10.8.x" } }, - "../marked-extended-tables": { - "version": "1.0.10", - "license": "MIT", - "devDependencies": { - "@babel/core": "^7.24.6", - "@babel/preset-env": "^7.25.4", - "@rollup/plugin-commonjs": "^26.0.1", - "@rollup/plugin-node-resolve": "^15.2.3", - "@semantic-release/changelog": "^6.0.3", - "@semantic-release/commit-analyzer": "^12.0.0", - "@semantic-release/git": "^10.0.1", - "@semantic-release/github": "^10.1.7", - "@semantic-release/npm": "^12.0.1", - "@semantic-release/release-notes-generator": "^13.0.0", - "babel-jest": "^29.5.0", - "eslint": "^8.57.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^6.1.1", - "jest-cli": "^29.7.0", - "marked": "^14.1.0", - "rollup": "^4.18.0", - "semantic-release": "^24.1.0" - }, - "peerDependencies": { - "marked": ">=3 <15" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -10572,8 +10543,13 @@ } }, "node_modules/marked-extended-tables": { - "resolved": "../marked-extended-tables", - "link": true + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.0.10.tgz", + "integrity": "sha512-zvRS0GPTkxq8UWawSDecd1Rxd2KD8crrmq2QALGDdrgkcgRNQzHlbnlujBGuXxdgDJg7f6UTv+JpcfejBpKdSg==", + "license": "MIT", + "peerDependencies": { + "marked": ">=3 <15" + } }, "node_modules/marked-gfm-heading-id": { "version": "3.2.0", diff --git a/package.json b/package.json index 87390b48d..8755d0699 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "file:../marked-extended-tables", + "marked-extended-tables": "^1.0.10", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", From 43222b7651040e981ee09ffc3207b8e3027588ab Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 4 Dec 2024 21:41:04 -0600 Subject: [PATCH 16/38] Fix test --- server/homebrew.api.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index de0d35e40..0af9863aa 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -1005,7 +1005,7 @@ brew`); expect(testBrew.theme).toEqual('5ePHB'); expect(testBrew.lang).toEqual('en'); // Style - expect(testBrew.style).toEqual('style\nstyle\nstyle'); + expect(testBrew.style).toEqual('style\nstyle\nstyle\n'); // Text expect(testBrew.text).toEqual('text\n'); }); From 6e5f071f2273fec3450464c83d349c3e52f758af Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 10 Dec 2024 21:21:41 -0600 Subject: [PATCH 17/38] Move Properties icon to the end of the snippets bar. --- client/homebrew/editor/snippetbar/snippetbar.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index d252c7120..00a826bc1 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -262,14 +262,14 @@ const Snippetbar = createClass({ onClick={()=>this.props.onViewChange('style')}> -
this.props.onViewChange('meta')}> - -
this.props.onViewChange('snip')}>
+
this.props.onViewChange('meta')}> + +
From dae297e0f54aa23333dbb3a9c1e19d3feabae223 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 10 Dec 2024 21:52:38 -0600 Subject: [PATCH 18/38] Partially implement disabled BrewSnippets --- client/homebrew/editor/snippetbar/snippetbar.jsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 00a826bc1..1809d8f7b 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -217,8 +217,6 @@ const Snippetbar = createClass({ renderEditorButtons : function(){ if(!this.props.showEditButtons) return; - - return (
{this.props.view !== 'meta' && <>
@@ -324,10 +322,11 @@ const SnippetGroup = createClass({ }, render : function(){ + const groupName = `groupName ${this.props.snippets.length === 0 ? 'disabled' : ''}`; return
- {this.props.groupName} + {this.props.groupName}
{this.renderSnippets(this.props.snippets)} From 86856605b94d50eef6aced21447d00d8ecf583aa Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 10 Dec 2024 23:08:51 -0600 Subject: [PATCH 19/38] Add editor highlighting --- client/homebrew/editor/editor.jsx | 22 +++++++++++++++++++--- client/homebrew/editor/editor.less | 8 ++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 95581e5d8..46fcf46c7 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -158,7 +158,7 @@ const Editor = createClass({ highlightCustomMarkdown : function(){ if(!this.codeEditor.current) return; - if(this.state.view === 'text') { + if((this.state.view === 'text') ||(this.state.view === 'snip')) { const codeMirror = this.codeEditor.current.codeMirror; codeMirror.operation(()=>{ // Batch CodeMirror styling @@ -178,8 +178,10 @@ const Editor = createClass({ for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear(); let editorPageCount = 2; // start page count from page 2 + let userSnippetCount = 1; // start snippet count from page 2 - _.forEach(this.props.brew.text.split('\n'), (line, lineNumber)=>{ + const whichSource = this.state.view === 'text' ? this.props.brew.text : this.props.brew.snippets; + _.forEach(whichSource.split('\n'), (line, lineNumber)=>{ //reset custom line styles codeMirror.removeLineClass(lineNumber, 'background', 'pageLine'); @@ -193,7 +195,7 @@ const Editor = createClass({ // Styling for \page breaks if((this.props.renderer == 'legacy' && line.includes('\\page')) || - (this.props.renderer == 'V3' && line.match(/^\\page$/))) { + (this.props.renderer == 'V3' && line.match(/^\\page$/) && this.state.view === 'text')) { // add back the original class 'background' but also add the new class '.pageline' codeMirror.addLineClass(lineNumber, 'background', 'pageLine'); @@ -206,12 +208,26 @@ const Editor = createClass({ editorPageCount += 1; }; + // New Codemirror styling for V3 renderer if(this.props.renderer == 'V3') { if(line.match(/^\\column$/)){ codeMirror.addLineClass(lineNumber, 'text', 'columnSplit'); } + // Styling for \snippet breaks + if(this.state.view === 'snip' && line.match(/^\\snippet\ .*$/)) { + + // add back the original class 'background' but also add the new class '.snippetLine' + codeMirror.addLineClass(lineNumber, 'background', 'snippetLine'); + const userSnippetCountElement = Object.assign(document.createElement('span'), { + className : 'editor-snippet-count', + textContent : userSnippetCount + }); + codeMirror.setBookmark({ line: lineNumber, ch: line.length }, userSnippetCountElement); + + userSnippetCount += 1; + }; // definition lists if(line.includes('::')){ if(/^:*$/.test(line) == true){ return; }; diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index b2e96683e..a73b596d7 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -10,10 +10,18 @@ background : #33333328; border-top : #333399 solid 1px; } + .snippetLine { + background : #33333328; + border-top : #333399 solid 1px; + } .editor-page-count { float : right; color : grey; } + .editor-snippet-count { + float : right; + color : grey; + } .columnSplit { font-style : italic; color : grey; From ed099aa061bef4ad783d64a459232beed0c12602 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 20 Dec 2024 21:47:05 -0600 Subject: [PATCH 20/38] Disable the BrewSnippets menu if empty. --- client/homebrew/editor/snippetbar/snippetbar.jsx | 6 +++--- client/homebrew/editor/snippetbar/snippetbar.less | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 1809d8f7b..b1fd02fd2 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -322,11 +322,11 @@ const SnippetGroup = createClass({ }, render : function(){ - const groupName = `groupName ${this.props.snippets.length === 0 ? 'disabled' : ''}`; - return
+ const snippetGroup = `snippetGroup snippetBarButton ${this.props.snippets.length === 0 ? 'disabledSnippets' : ''}`; + return
- {this.props.groupName} + {this.props.groupName}
{this.renderSnippets(this.props.snippets)} diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 33242174b..3478dfde0 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -231,6 +231,13 @@ } } } + .disabledSnippets { + color: grey; + cursor: not-allowed; + + &:hover { background-color: #DDDDDD;} + } + } @container editor (width < 553px) { .snippetBar { From 662f039daa9437317cd128271d2962ecfbd32fb0 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 12 Jan 2025 14:13:27 -0600 Subject: [PATCH 21/38] Merge conflict clearing --- package-lock.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 072108b1f..d05e97f62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "classnames": "^2.5.1", "codemirror": "^5.65.6", "cookie-parser": "^1.4.7", - "core-js": "^3.39.0", + "core-js": "^3.40.0", "cors": "^2.8.5", "create-react-class": "^15.7.0", "dedent-tabs": "^0.10.3", @@ -36,17 +36,17 @@ "lodash": "^4.17.21", "marked": "11.2.0", "marked-emoji": "^1.4.3", - "marked-extended-tables": "^1.0.10", + "marked-extended-tables": "^1.1.0", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.9.2", + "mongoose": "^8.9.4", "nanoid": "5.0.9", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-frame-component": "^4.1.3", + "react-frame-component": "^5.2.7", "react-router": "^7.1.1", "sanitize-filename": "1.6.3", "superagent": "^10.1.1", @@ -54,7 +54,7 @@ }, "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.1", - "babel-plugin-transform-import-meta": "^2.2.1", + "babel-plugin-transform-import-meta": "^2.3.2", "eslint": "^9.17.0", "eslint-plugin-jest": "^28.10.0", "eslint-plugin-react": "^7.37.3", @@ -3678,14 +3678,14 @@ } }, "node_modules/babel-plugin-transform-import-meta": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.2.1.tgz", - "integrity": "sha512-AxNh27Pcg8Kt112RGa3Vod2QS2YXKKJ6+nSvRtv7qQTJAdx0MZa4UHZ4lnxHUWA2MNbLuZQv5FVab4P1CoLOWw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.2.tgz", + "integrity": "sha512-902o4GiQqI1GqAXfD5rEoz0PJamUfJ3VllpdWaNsFTwdaNjFSFHawvBO+cp5K2j+g2h3bZ4lnM1Xb6yFYGihtA==", "dev": true, "license": "BSD", "dependencies": { - "@babel/template": "^7.4.4", - "tslib": "^2.4.0" + "@babel/template": "^7.25.9", + "tslib": "^2.8.1" }, "peerDependencies": { "@babel/core": "^7.10.0" @@ -4645,9 +4645,9 @@ } }, "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==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", + "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -9868,12 +9868,12 @@ } }, "node_modules/marked-extended-tables": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.0.10.tgz", - "integrity": "sha512-zvRS0GPTkxq8UWawSDecd1Rxd2KD8crrmq2QALGDdrgkcgRNQzHlbnlujBGuXxdgDJg7f6UTv+JpcfejBpKdSg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/marked-extended-tables/-/marked-extended-tables-1.1.0.tgz", + "integrity": "sha512-xPQlnmr/mpIJEjwg9/guSKzxoKu7hyCD/sM59mcZc+nMIh2JuVM2se+kCa1Jo1UH+BEHcNlZ221ziJ/cOxAgCA==", "license": "MIT", "peerDependencies": { - "marked": ">=3 <15" + "marked": ">=3 <16" } }, "node_modules/marked-gfm-heading-id": { @@ -10254,9 +10254,9 @@ } }, "node_modules/mongoose": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.2.tgz", - "integrity": "sha512-mLWynmZS1v8HTeMxyLhskQncS1SkrjW1eLNuFDYGQMQ/5QrFrxTLNwWXeCRZeKT2lXyaxW8bnJC9AKPT9jYMkw==", + "version": "8.9.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.4.tgz", + "integrity": "sha512-DndoI01aV/q40P9DiYDXsYjhj8vZjmmuFwcC3Tro5wFznoE1z6Fe2JgMnbLR6ghglym5ziYizSfAJykp+UPZWg==", "license": "MIT", "dependencies": { "bson": "^6.10.1", @@ -11675,9 +11675,9 @@ } }, "node_modules/react-frame-component": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-4.1.3.tgz", - "integrity": "sha512-4PurhctiqnmC1F5prPZ+LdsalH7pZ3SFA5xoc0HBe8mSHctdLLt4Cr2WXfXOoajHBYq/yiipp9zOgx+vy8GiEA==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-5.2.7.tgz", + "integrity": "sha512-ROjHtSLoSVYUBfTieazj/nL8jIX9rZFmHC0yXEU+dx6Y82OcBEGgU9o7VyHMrBFUN9FuQ849MtIPNNLsb4krbg==", "license": "MIT", "peerDependencies": { "prop-types": "^15.5.9", From 004729b2a4f0ad27711a1c60a9ba415c4ad47141 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 28 Jan 2025 19:37:02 -0600 Subject: [PATCH 22/38] Fix editor regression. --- client/homebrew/editor/editor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 46fcf46c7..2d349252a 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -181,7 +181,7 @@ const Editor = createClass({ let userSnippetCount = 1; // start snippet count from page 2 const whichSource = this.state.view === 'text' ? this.props.brew.text : this.props.brew.snippets; - _.forEach(whichSource.split('\n'), (line, lineNumber)=>{ + _.forEach(whichSource?.split('\n'), (line, lineNumber)=>{ //reset custom line styles codeMirror.removeLineClass(lineNumber, 'background', 'pageLine'); From b605346c7dab4b66696e038139e336466a018f44 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 14 Mar 2025 18:36:18 -0500 Subject: [PATCH 23/38] Fix regeression in snippets --- client/homebrew/pages/editPage/editPage.jsx | 1 - client/homebrew/pages/homePage/homePage.jsx | 1 - client/homebrew/pages/newPage/newPage.jsx | 1 - shared/helpers.js | 4 ++-- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 494de6c88..b209e7ef7 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -469,7 +469,6 @@ const EditPage = createClass({ renderer={this.state.brew.renderer} userThemes={this.props.userThemes} themeBundle={this.state.themeBundle} - snippetBundle={this.state.themeBundle.snippets} updateBrew={this.updateBrew} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 0a598556a..45efedf6a 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -108,7 +108,6 @@ const HomePage = createClass({ onTextChange={this.handleTextChange} renderer={this.state.brew.renderer} showEditButtons={false} - snippets={this.props.snippets} themeBundle={this.state.themeBundle} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index cb6ab5c76..6daa881f6 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -246,7 +246,6 @@ const NewPage = createClass({ onSnipChange={this.handleSnipChange} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} - snippets={this.props.snippets} themeBundle={this.state.themeBundle} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} diff --git a/shared/helpers.js b/shared/helpers.js index 1f6ccc936..efe7eb008 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -4,7 +4,7 @@ import request from '../client/homebrew/utils/request-middleware.js'; // Convert the templates from a brew to a Snippets Structure. const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=null, full=true)=>{ - const textSplit = /^\\snippet /gm; + const textSplit = /^\\snippet +/gm; const mpAsSnippets = []; // Snippets from Themes first. if(themeBundleSnippets) { @@ -15,7 +15,7 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=nul const name = snips.trim().split('\n')[0]; if(name.length != 0) { userSnippets.push({ - name : name.slice('\snippets'.length), + name : name, icon : '', gen : snips.slice(name.length + 1).trim(), }); From 99efe7f06bf2406e5ac43267c64c985c5fa47a14 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 14 Mar 2025 19:26:37 -0500 Subject: [PATCH 24/38] Add default value for document name in snippets menu --- client/homebrew/editor/snippetbar/snippetbar.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index b1fd02fd2..197461b52 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -121,7 +121,7 @@ const Snippetbar = createClass({ } } - const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title, this.props.brew.snippets, this.props.themeBundle.snippets); + const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title || 'New Document', this.props.brew.snippets, this.props.themeBundle.snippets); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; From a62588a4c9e495f7281b4178b05a02c30046739c Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 24 Mar 2025 14:58:14 -0500 Subject: [PATCH 25/38] Fix fouled up regex that only worked by accident --- shared/helpers.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index efe7eb008..997d77cec 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -4,20 +4,22 @@ import request from '../client/homebrew/utils/request-middleware.js'; // Convert the templates from a brew to a Snippets Structure. const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=null, full=true)=>{ - const textSplit = /^\\snippet +/gm; + const textSplit = /^(\\snippet +.+\n)/gm; const mpAsSnippets = []; // Snippets from Themes first. if(themeBundleSnippets) { for (let themes of themeBundleSnippets) { if(typeof themes !== 'string') { const userSnippets = []; - for (let snips of themes.snippets.trim().split(textSplit)) { - const name = snips.trim().split('\n')[0]; - if(name.length != 0) { + const snipSplit = themes.snippets.trim().split(textSplit).slice(1); + for (let snips = 0; snips < snipSplit.length; snips+=2) { + if(!snipSplit[snips].startsWith('\\snippet ')) break; + const snippetName = snipSplit[snips].split(/\\snippet +/)[1].split('\n')[0].trim(); + if(snippetName.length != 0) { userSnippets.push({ - name : name, + name : snippetName, icon : '', - gen : snips.slice(name.length + 1).trim(), + gen : snipSplit[snips + 1], }); } } @@ -35,16 +37,14 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=nul // Local Snippets if(userBrewSnippets) { const userSnippets = []; - for (let snips of userBrewSnippets.trim().split(textSplit)) { - let name = snips.split('\n')[0]; - let justSnippet = snips.slice(name.length + 1); - if(justSnippet.slice(-1) === '\n') { - justSnippet = justSnippet.slice(0, -1); - } - if(name.length != 0) { + const snipSplit = userBrewSnippets.trim().split(textSplit).slice(1); + for (let snips = 0; snips < snipSplit.length; snips+=2) { + if(!snipSplit[snips].startsWith('\\snippet ')) break; + const snippetName = snipSplit[snips].split(/\\snippet +/)[1].split('\n')[0].trim(); + if(snippetName.length != 0) { const subSnip = { - name : name, - gen : justSnippet, + name : snippetName, + gen : snipSplit[snips + 1], }; // if(full) subSnip.icon = ''; userSnippets.push(subSnip); From 565d58bb31e77d75742057966a322bdea8ed80b8 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 24 Mar 2025 21:06:55 -0500 Subject: [PATCH 26/38] Add clearing for snippets --- client/homebrew/editor/editor.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index cdad4abb3..7800717d5 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -186,6 +186,7 @@ const Editor = createClass({ //reset custom line styles codeMirror.removeLineClass(lineNumber, 'background', 'pageLine'); + codeMirror.removeLineClass(lineNumber, 'background', 'snippetLine'); codeMirror.removeLineClass(lineNumber, 'text'); codeMirror.removeLineClass(lineNumber, 'wrap', 'sourceMoveFlash'); From 7525e087ff0264f9ae28508b2b3f3619a3528511 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 29 Mar 2025 18:47:03 -0500 Subject: [PATCH 27/38] Regression Fix WIP --- client/homebrew/editor/snippetbar/snippetbar.jsx | 9 +++------ client/homebrew/pages/editPage/editPage.jsx | 1 + client/homebrew/pages/homePage/homePage.jsx | 3 ++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index c8c8fb590..ac3062ecf 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -101,10 +101,11 @@ const Snippetbar = createClass({ if(key == 'snippets') { const result = _.reverse(_.unionBy(_.reverse(newValue), _.reverse(oldValue), 'name')); // Join snippets together, with preference for the child theme over the parent theme return result.filter((snip)=>snip.gen || snip.subsnippets); - } + }; }, compileSnippets : function() { + console.log('compileSnippets'); let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); @@ -122,6 +123,7 @@ const Snippetbar = createClass({ } const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title || 'New Document', this.props.brew.snippets, this.props.themeBundle.snippets); + console.log(userSnippetsasJSON); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; @@ -283,11 +285,6 @@ const Snippetbar = createClass({ module.exports = Snippetbar; - - - - - const SnippetGroup = createClass({ displayName : 'SnippetGroup', getDefaultProps : function() { diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index b209e7ef7..a4d8a1ed4 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -451,6 +451,7 @@ const EditPage = createClass({ }, render : function(){ + console.log(this.state.themeBundle); return
{this.renderNavbar()} diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index b9c1b7371..47cb23d50 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -97,6 +97,7 @@ const HomePage = createClass({ }, render : function(){ + console.log(this.state.themeBundle); return
{this.renderNavbar()} @@ -108,7 +109,7 @@ const HomePage = createClass({ onTextChange={this.handleTextChange} renderer={this.state.brew.renderer} showEditButtons={false} - snippetBundle={this.state.themeBundle.snippets} + themeBundle={this.state.themeBundle} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} currentEditorViewPageNum={this.state.currentEditorViewPageNum} From 9d1601f4244813407321ba6bfc24946644e530a6 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 29 Mar 2025 19:14:10 -0500 Subject: [PATCH 28/38] Seems to be working - no idea why... --- client/homebrew/editor/snippetbar/snippetbar.jsx | 2 -- client/homebrew/pages/editPage/editPage.jsx | 1 - client/homebrew/pages/homePage/homePage.jsx | 1 - 3 files changed, 4 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index ac3062ecf..8c6872ab4 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -105,7 +105,6 @@ const Snippetbar = createClass({ }, compileSnippets : function() { - console.log('compileSnippets'); let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); @@ -123,7 +122,6 @@ const Snippetbar = createClass({ } const userSnippetsasJSON = brewSnippetsToJSON(this.props.brew.title || 'New Document', this.props.brew.snippets, this.props.themeBundle.snippets); - console.log(userSnippetsasJSON); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index a4d8a1ed4..b209e7ef7 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -451,7 +451,6 @@ const EditPage = createClass({ }, render : function(){ - console.log(this.state.themeBundle); return
{this.renderNavbar()} diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 47cb23d50..d03e30c91 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -97,7 +97,6 @@ const HomePage = createClass({ }, render : function(){ - console.log(this.state.themeBundle); return
{this.renderNavbar()} From 2ce7c6c2be86e89b22e794472e5da344d1234459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 00:14:03 +0200 Subject: [PATCH 29/38] css breakpoint changed --- client/homebrew/editor/snippetbar/snippetbar.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 7a39173e6..5c98ccfda 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -237,7 +237,7 @@ } } -@container editor (width < 553px) { +@container editor (width < 681px) { .snippetBar { .editors { flex : 1; From b9b45632b0ac714ab948268f37ad2facd728c92e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 00:19:43 +0200 Subject: [PATCH 30/38] fix package-lock --- package-lock.json | 123 +++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2d060d210..450d4e364 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,11 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.26.9", - "@babel/plugin-transform-runtime": "^7.26.9", + "@babel/core": "^7.26.10", + "@babel/plugin-transform-runtime": "^7.26.10", "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", - "@googleapis/drive": "^8.16.0", + "@googleapis/drive": "^11.0.0", "body-parser": "^1.20.2", "classnames": "^2.5.1", "codemirror": "^5.65.6", @@ -33,7 +33,7 @@ "jwt-simple": "^0.5.6", "less": "^3.13.1", "lodash": "^4.17.21", - "marked": "14.0.0", + "marked": "15.0.0", "marked-emoji": "^2.0.0", "marked-extended-tables": "^2.0.1", "marked-gfm-heading-id": "^4.0.1", @@ -41,21 +41,21 @@ "marked-subsuper-text": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.12.1", - "nanoid": "5.1.3", + "mongoose": "^8.13.0", + "nanoid": "5.1.5", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-frame-component": "^4.1.3", - "react-router": "^7.3.0", + "react-router": "^7.4.0", "sanitize-filename": "1.6.3", - "superagent": "^10.1.1", + "superagent": "^10.2.0", "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" }, "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.22.0", + "eslint": "^9.23.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", "globals": "^16.0.0", @@ -63,10 +63,10 @@ "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", - "stylelint": "^16.16.0", + "stylelint": "^16.17.0", "stylelint-config-recess-order": "^6.0.0", "stylelint-config-recommended": "^15.0.0", - "supertest": "^7.0.0" + "supertest": "^7.1.0" }, "engines": { "node": "^20.18.x", @@ -1863,9 +1863,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", - "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.0.tgz", + "integrity": "sha512-yJLLmLexii32mGrhW29qvU3QBVTu0GUmEf/J4XsBtVhp4JkIUFN/BjWqTF63yRvGApIDpZm5fa97LtYtINmfeQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1886,9 +1886,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", - "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1923,9 +1923,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", - "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", + "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", "dev": true, "license": "MIT", "engines": { @@ -1957,9 +1957,9 @@ } }, "node_modules/@googleapis/drive": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-8.16.0.tgz", - "integrity": "sha512-Xi2mMrUTQ+gsfyouRGd0pfnL+jjg4n4sjKsJruM1y4DknuRfdSBTk5E//WrL0YJ/CqpcBgyd7L8DvaPRtxZD3Q==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-11.0.0.tgz", + "integrity": "sha512-vhkl6/MZ8k5h5XOyenWOD4ys+SNdb8wKYvzU6OBGFx/TzJyHRm4JwgvE8uVDFU6efzNRS0mOiNRfY6nrmHOTtg==", "license": "Apache-2.0", "dependencies": { "googleapis-common": "^7.0.0" @@ -5690,19 +5690,19 @@ "license": "MIT" }, "node_modules/eslint": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", - "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", + "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", - "@eslint/config-helpers": "^0.1.0", + "@eslint/config-helpers": "^0.2.0", "@eslint/core": "^0.12.0", - "@eslint/eslintrc": "^3.3.0", - "@eslint/js": "9.22.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.23.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -9915,9 +9915,9 @@ } }, "node_modules/marked": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", - "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.0.tgz", + "integrity": "sha512-0mouKmBROJv/WSHJBPZZyYofUgawMChnD5je/g+aOBXsHDjb/IsnTQj7mnhQZu+qPJmRQ0ecX3mLGEUm3BgwYA==", "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -10297,9 +10297,9 @@ } }, "node_modules/mongodb-connection-string-url/node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.0.tgz", + "integrity": "sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==", "license": "MIT", "dependencies": { "punycode": "^2.3.1" @@ -10318,12 +10318,12 @@ } }, "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.1.tgz", - "integrity": "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", "license": "MIT", "dependencies": { - "tr46": "^5.0.0", + "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" }, "engines": { @@ -10331,14 +10331,14 @@ } }, "node_modules/mongoose": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.12.1.tgz", - "integrity": "sha512-UW22y8QFVYmrb36hm8cGncfn4ARc/XsYWQwRTaj0gxtQk1rDuhzDO1eBantS+hTTatfAIS96LlRCJrcNHvW5+Q==", + "version": "8.13.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.13.1.tgz", + "integrity": "sha512-sRqlXI+6jhr9/KicCOjet1VVPONFsOxTrh14tfueX5y3GJ2ihswc5ewUUojuwdSS/5koGXLIPmGivDSApVXflA==", "license": "MIT", "dependencies": { "bson": "^6.10.3", "kareem": "2.6.3", - "mongodb": "~6.14.0", + "mongodb": "~6.15.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -10414,9 +10414,9 @@ } }, "node_modules/mongoose/node_modules/mongodb": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.14.2.tgz", - "integrity": "sha512-kMEHNo0F3P6QKDq17zcDuPeaywK/YaJVCEQRzPF3TOM/Bl9MFg64YE5Tu7ifj37qZJMhwU1tl2Ioivws5gRG5Q==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.15.0.tgz", + "integrity": "sha512-ifBhQ0rRzHDzqp9jAQP6OwHSH7dbYIQjD3SbJs9YYk9AikKEettW/9s/tbSFDTpXcRbF+u1aLrhHxDFaYtZpFQ==", "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.9", @@ -10493,9 +10493,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.3.tgz", - "integrity": "sha512-zAbEOEr7u2CbxwoMRlz/pNSpRP0FdAU4pRaYunCdEezWohXFs+a0Xw7RfkKaezMsmSM1vttcLthJtwRnVtOfHQ==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", + "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", "funding": [ { "type": "github", @@ -11770,9 +11770,9 @@ "license": "MIT" }, "node_modules/react-router": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.3.0.tgz", - "integrity": "sha512-466f2W7HIWaNXTKM5nHTqNxLrHTyXybm7R0eBlVSt0k/u55tTCDO194OIx/NrYD4TS5SXKTNekXfT37kMKUjgw==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.4.1.tgz", + "integrity": "sha512-Vmizn9ZNzxfh3cumddqv3kLOKvc7AskUT0dC1prTabhiEi0U4A33LmkDOJ79tXaeSqCqMBXBU/ySX88W85+EUg==", "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", @@ -13169,9 +13169,9 @@ "license": "ISC" }, "node_modules/stylelint": { - "version": "16.16.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.16.0.tgz", - "integrity": "sha512-40X5UOb/0CEFnZVEHyN260HlSSUxPES+arrUphOumGWgXERHfwCD0kNBVILgQSij8iliYVwlc0V7M5bcLP9vPg==", + "version": "16.17.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.17.0.tgz", + "integrity": "sha512-I9OwVIWRMqVm2Br5iTbrfSqGRPWQUlvm6oXO1xZuYYu0Gpduy67N8wXOZv15p6E/JdlZiAtQaIoLKZEWk5hrjw==", "dev": true, "funding": [ { @@ -13428,9 +13428,10 @@ } }, "node_modules/superagent": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.1.1.tgz", - "integrity": "sha512-9pIwrHrOj3uAnqg9gDlW7EA2xv+N5au/dSM0kM22HTqmUu8jBxNT+8uA7tA3UoCnmiqzpSbu8rasIUZvbyamMQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.0.tgz", + "integrity": "sha512-IKeoGox6oG9zyDeizaezkJ2/aK0wc5la9st7WsAKyrAkfJ56W3whVbVtF68k6wuc87/y9T85NyON5FLz7Mrzzw==", + "license": "MIT", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.4", @@ -13459,9 +13460,9 @@ } }, "node_modules/supertest": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz", - "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.0.tgz", + "integrity": "sha512-5QeSO8hSrKghtcWEoPiO036fxH0Ii2wVQfFZSP0oqQhmjk8bOLhDFXr4JrvaFmPuEWUoq4znY3uSi8UzLKxGqw==", "dev": true, "license": "MIT", "dependencies": { From de1773361ae0d0f2977e221c0e3a7fe9feb597e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 00:40:00 +0200 Subject: [PATCH 31/38] final css fix --- client/homebrew/editor/snippetbar/snippetbar.less | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 5c98ccfda..d7c8d3847 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -14,13 +14,13 @@ .snippets { display : flex; justify-content : flex-start; - min-width : 327.58px; + min-width : 432.18px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied } .editors { display : flex; justify-content : flex-end; - min-width : 225px; + min-width : 250px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied &:only-child {min-width : unset; margin-left : auto;} @@ -237,7 +237,7 @@ } } -@container editor (width < 681px) { +@container editor (width < 682px) { .snippetBar { .editors { flex : 1; From f5fc106d0184660fea8a2c13c99d6e1289789963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 00:52:41 +0200 Subject: [PATCH 32/38] pixel frame fix --- client/homebrew/editor/snippetbar/snippetbar.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index d7c8d3847..a0691f8b6 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -237,7 +237,7 @@ } } -@container editor (width < 682px) { +@container editor (width < 683px) { .snippetBar { .editors { flex : 1; From 4eeaa7c650e7becbca773833c0a1efcea0779e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Mon, 31 Mar 2025 17:11:25 +0200 Subject: [PATCH 33/38] default text for snippet tab --- client/homebrew/editor/editor.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 7800717d5..411476131 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -22,7 +22,13 @@ const DEFAULT_STYLE_TEXT = dedent` color: black; }`; -const DEFAULT_SNIPPET_TEXT = ``; +const DEFAULT_SNIPPET_TEXT = dedent` + \snippet example snippet + + The text between \`\snippet title\` lines will become a snippet of name \`title\` as this example provides. + + This snippet is accessible in the brew tab, and will be inherited if the brew is used as a theme. +`; let isJumping = false; const Editor = createClass({ From 8e8f520eaaed2b8929b8e7a19905890912ea4399 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 31 Mar 2025 20:50:54 -0500 Subject: [PATCH 34/38] Fix Highlighting issue with new brew sample snippets --- client/homebrew/editor/editor.jsx | 32 +++++++++++++------------------ 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 411476131..7112aa4b9 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -13,6 +13,7 @@ const MetadataEditor = require('./metadataEditor/metadataEditor.jsx'); const EDITOR_THEME_KEY = 'HOMEBREWERY-EDITOR-THEME'; const PAGEBREAK_REGEX_V3 = /^(?=\\page(?: *{[^\n{}]*})?$)/m; +const SNIPPETBREAK_REGEX_V3 = /^\\snippet\ .*$/; const SNIPPETBAR_HEIGHT = 25; const DEFAULT_STYLE_TEXT = dedent` /*=======--- Example CSS styling ---=======*/ @@ -155,6 +156,7 @@ const Editor = createClass({ handleViewChange : function(newView){ this.props.setMoveArrows(newView === 'text'); + this.setState({ view : newView }, ()=>{ @@ -190,6 +192,9 @@ const Editor = createClass({ const whichSource = this.state.view === 'text' ? this.props.brew.text : this.props.brew.snippets; _.forEach(whichSource?.split('\n'), (line, lineNumber)=>{ + const tabHighlight = this.state.view === 'text' ? 'pageLine' : 'snippetLine'; + const textOrSnip = this.state.view === 'text'; + //reset custom line styles codeMirror.removeLineClass(lineNumber, 'background', 'pageLine'); codeMirror.removeLineClass(lineNumber, 'background', 'snippetLine'); @@ -203,40 +208,28 @@ const Editor = createClass({ // Styling for \page breaks if((this.props.renderer == 'legacy' && line.includes('\\page')) || - (this.props.renderer == 'V3' && line.match(PAGEBREAK_REGEX_V3))) { + (this.props.renderer == 'V3' && line.match(textOrSnip ? PAGEBREAK_REGEX_V3 : SNIPPETBREAK_REGEX_V3))) { - if(lineNumber > 0) // Since \page is optional on first line of document, + if((lineNumber > 0) && (textOrSnip)) // Since \page is optional on first line of document, editorPageCount += 1; // don't use it to increment page count; stay at 1 + else if(this.state.view !== 'text') userSnippetCount += 1; // add back the original class 'background' but also add the new class '.pageline' - codeMirror.addLineClass(lineNumber, 'background', 'pageLine'); + codeMirror.addLineClass(lineNumber, 'background', tabHighlight); const pageCountElement = Object.assign(document.createElement('span'), { className : 'editor-page-count', - textContent : editorPageCount + textContent : textOrSnip ? editorPageCount : userSnippetCount }); codeMirror.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement); }; // New Codemirror styling for V3 renderer - if(this.props.renderer == 'V3') { + if(this.props.renderer === 'V3') { if(line.match(/^\\column$/)){ codeMirror.addLineClass(lineNumber, 'text', 'columnSplit'); } - // Styling for \snippet breaks - if(this.state.view === 'snip' && line.match(/^\\snippet\ .*$/)) { - - // add back the original class 'background' but also add the new class '.snippetLine' - codeMirror.addLineClass(lineNumber, 'background', 'snippetLine'); - const userSnippetCountElement = Object.assign(document.createElement('span'), { - className : 'editor-snippet-count', - textContent : userSnippetCount - }); - codeMirror.setBookmark({ line: lineNumber, ch: line.length }, userSnippetCountElement); - - userSnippetCount += 1; - }; // definition lists if(line.includes('::')){ if(/^:*$/.test(line) == true){ return; }; @@ -490,12 +483,13 @@ const Editor = createClass({ } if(this.isSnip()){ + if(!this.props.brew.snippets) { this.props.brew.snippets = DEFAULT_SNIPPET_TEXT; } return <> Date: Mon, 7 Apr 2025 23:22:47 -0500 Subject: [PATCH 35/38] Move Snippets store to metadata block. Note this still stores the snippets as a string for the passed about brew object. --- server/homebrew.api.js | 7 +------ shared/helpers.js | 6 +----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 4534c5cb7..84e338ef4 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -170,12 +170,6 @@ const api = { mergeBrewText : (brew)=>{ let text = brew.text; - if(brew.snippets !== undefined) { - text = `\`\`\`snippets\n` + - `${yaml.dump(brewSnippetsToJSON('brew_snippets', brew.snippets, null, false))}` + - `\`\`\`\n\n` + - `${text}`; - } if(brew.style !== undefined) { text = `\`\`\`css\n` + `${brew.style || ''}\n` + @@ -183,6 +177,7 @@ const api = { `${text}`; } const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']); + metadata.snippets = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false); text = `\`\`\`metadata\n` + `${yaml.dump(metadata)}\n` + `\`\`\`\n\n` + diff --git a/shared/helpers.js b/shared/helpers.js index 997d77cec..e4dc9eba8 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -91,6 +91,7 @@ const splitTextStyleAndMetadata = (brew)=>{ const metadataSection = brew.text.slice(11, index + 1); const metadata = yaml.load(metadataSection); Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); + brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets); brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```css')) { @@ -98,11 +99,6 @@ const splitTextStyleAndMetadata = (brew)=>{ brew.style = brew.text.slice(7, index + 1); brew.text = brew.text.slice(index + 6); } - if(brew.text.startsWith('```snippets')) { - const index = brew.text.indexOf('\n```\n\n'); - brew.snippets = yamlSnippetsToText(yaml.load(brew.text.slice(11, index + 1))).slice(0, -1); - brew.text = brew.text.slice(index + 6); - } // Handle old brews that still have empty strings in the tags metadata if(typeof brew.tags === 'string') brew.tags = brew.tags ? [brew.tags] : []; From 9f56d100aaf5a250715fc70872e3410237378625 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 8 Apr 2025 00:32:11 -0500 Subject: [PATCH 36/38] change tab --- client/homebrew/editor/editor.jsx | 6 +++--- client/homebrew/editor/snippetbar/snippetbar.jsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 7112aa4b9..77da1fcd9 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -61,7 +61,7 @@ const Editor = createClass({ getInitialState : function() { return { editorTheme : this.props.editorTheme, - view : 'text' //'text', 'style', 'meta', 'snip' + view : 'text' //'text', 'style', 'meta', 'snippet' }; }, @@ -71,7 +71,7 @@ const Editor = createClass({ isText : function() {return this.state.view == 'text';}, isStyle : function() {return this.state.view == 'style';}, isMeta : function() {return this.state.view == 'meta';}, - isSnip : function() {return this.state.view == 'snip';}, + isSnip : function() {return this.state.view == 'snippet';}, componentDidMount : function() { @@ -167,7 +167,7 @@ const Editor = createClass({ highlightCustomMarkdown : function(){ if(!this.codeEditor.current) return; - if((this.state.view === 'text') ||(this.state.view === 'snip')) { + if((this.state.view === 'text') ||(this.state.view === 'snippet')) { const codeMirror = this.codeEditor.current.codeMirror; codeMirror.operation(()=>{ // Batch CodeMirror styling diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index 8c6872ab4..5e2051a86 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -259,8 +259,8 @@ const Snippetbar = createClass({ onClick={()=>this.props.onViewChange('style')}>
-
this.props.onViewChange('snip')}> +
this.props.onViewChange('snippet')}>
Date: Tue, 8 Apr 2025 20:29:32 -0500 Subject: [PATCH 37/38] A little bit of cleanup and structure flattening Fixes failed tests. --- server/homebrew.api.js | 3 ++- shared/helpers.js | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 84e338ef4..8a98d50a8 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -177,7 +177,8 @@ const api = { `${text}`; } const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']); - metadata.snippets = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false); + const snippetsArray = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false).snippets; + metadata.snippets = snippetsArray.length > 0 ? snippetsArray : undefined; text = `\`\`\`metadata\n` + `${yaml.dump(metadata)}\n` + `\`\`\`\n\n` + diff --git a/shared/helpers.js b/shared/helpers.js index e4dc9eba8..0ca681dfb 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -76,7 +76,8 @@ const yamlSnippetsToText = (yamlObj)=>{ if(typeof yamlObj == 'string') return yamlObj; let snippetsText = ''; - for (let snippet of yamlObj.snippets) { + + for (let snippet of yamlObj) { for (let subSnippet of snippet.subsnippets) { snippetsText = `${snippetsText}\\snippet ${subSnippet.name}\n${subSnippet.gen || ''}\n`; } @@ -91,7 +92,7 @@ const splitTextStyleAndMetadata = (brew)=>{ const metadataSection = brew.text.slice(11, index + 1); const metadata = yaml.load(metadataSection); Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); - brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets); + brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets || ''); brew.text = brew.text.slice(index + 6); } if(brew.text.startsWith('```css')) { From a6703ef731a1136031945e0738c1021b6f5dfd8f Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 9 Apr 2025 13:30:03 -0500 Subject: [PATCH 38/38] Clear up confusing commment and consolidate style tag. --- client/homebrew/editor/editor.jsx | 2 +- client/homebrew/editor/editor.less | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 3179a1c5f..6859c5aa2 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -171,7 +171,7 @@ const Editor = createClass({ for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear(); - let userSnippetCount = 1; // start snippet count from page 2 + let userSnippetCount = 1; // start snippet count from snippet 1 let editorPageCount = 1; // start page count from page 1 const whichSource = this.state.view === 'text' ? this.props.brew.text : this.props.brew.snippets; diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index 5d84e488b..7fbed0ff7 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -7,11 +7,7 @@ .codeEditor { height : 100%; .CodeMirror { height : 100%; } - .pageLine { - background : #33333328; - border-top : #333399 solid 1px; - } - .snippetLine { + .pageLine, .snippetLine { background : #33333328; border-top : #333399 solid 1px; }