mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-24 20:42:43 +00:00
Merge branch 'master' into experimentalLocalStorageHistory
This commit is contained in:
@@ -17,7 +17,7 @@ const NotificationPopup = ()=>{
|
|||||||
<ul>
|
<ul>
|
||||||
<li key='Vault'>
|
<li key='Vault'>
|
||||||
<em>Search brews with our new page!</em><br />
|
<em>Search brews with our new page!</em><br />
|
||||||
We have been working very hard in making this possible, now you can share your work and look at it in the new <a href="/vault">Vault</a> page!
|
We have been working very hard in making this possible, now you can share your work and look at it in the new <a href='/vault'>Vault</a> page!
|
||||||
All PUBLISHED brews will be available to anyone searching there, by title or author, and filtering by renderer.
|
All PUBLISHED brews will be available to anyone searching there, by title or author, and filtering by renderer.
|
||||||
|
|
||||||
More features will be coming.
|
More features will be coming.
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
|
|||||||
|
|
||||||
} else if(mode == 'fit'){
|
} else if(mode == 'fit'){
|
||||||
// find the page with the largest single dim (height or width) so that zoom can be adapted to fit it.
|
// find the page with the largest single dim (height or width) so that zoom can be adapted to fit it.
|
||||||
const minDimRatio = [...pages].reduce((minRatio, page) => Math.min(minRatio, iframeWidth / page.offsetWidth, iframeHeight / page.offsetHeight), Infinity);
|
const minDimRatio = [...pages].reduce((minRatio, page)=>Math.min(minRatio, iframeWidth / page.offsetWidth, iframeHeight / page.offsetHeight), Infinity);
|
||||||
|
|
||||||
desiredZoom = minDimRatio * 100;
|
desiredZoom = minDimRatio * 100;
|
||||||
}
|
}
|
||||||
@@ -67,9 +67,9 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
|
|||||||
return deltaZoom;
|
return deltaZoom;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`toolBar ${toolsVisible ? 'visible' : 'hidden'}`}>
|
<div className={`toolBar ${toolsVisible ? 'visible' : 'hidden'}`}>
|
||||||
<button className='toggleButton' title={`${toolsVisible ? 'Hide' : 'Show'} Preview Toolbar`} onClick={()=>{setToolsVisible(!toolsVisible)}}><i className='fas fa-glasses' /></button>
|
<button className='toggleButton' title={`${toolsVisible ? 'Hide' : 'Show'} Preview Toolbar`} onClick={()=>{setToolsVisible(!toolsVisible);}}><i className='fas fa-glasses' /></button>
|
||||||
{/*v=====----------------------< Zoom Controls >---------------------=====v*/}
|
{/*v=====----------------------< Zoom Controls >---------------------=====v*/}
|
||||||
<div className='group'>
|
<div className='group'>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const Editor = createClass({
|
|||||||
onStyleChange : ()=>{},
|
onStyleChange : ()=>{},
|
||||||
onMetaChange : ()=>{},
|
onMetaChange : ()=>{},
|
||||||
reportError : ()=>{},
|
reportError : ()=>{},
|
||||||
|
|
||||||
onCursorPageChange : ()=>{},
|
onCursorPageChange : ()=>{},
|
||||||
onViewPageChange : ()=>{},
|
onViewPageChange : ()=>{},
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ const Editor = createClass({
|
|||||||
|
|
||||||
currentEditorCursorPageNum : 1,
|
currentEditorCursorPageNum : 1,
|
||||||
currentEditorViewPageNum : 1,
|
currentEditorViewPageNum : 1,
|
||||||
currentBrewRendererPageNum : 1,
|
currentBrewRendererPageNum : 1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getInitialState : function() {
|
getInitialState : function() {
|
||||||
@@ -70,8 +70,8 @@ const Editor = createClass({
|
|||||||
document.getElementById('BrewRenderer').addEventListener('keydown', this.handleControlKeys);
|
document.getElementById('BrewRenderer').addEventListener('keydown', this.handleControlKeys);
|
||||||
document.addEventListener('keydown', this.handleControlKeys);
|
document.addEventListener('keydown', this.handleControlKeys);
|
||||||
|
|
||||||
this.codeEditor.current.codeMirror.on('cursorActivity', (cm)=>{this.updateCurrentCursorPage(cm.getCursor())});
|
this.codeEditor.current.codeMirror.on('cursorActivity', (cm)=>{this.updateCurrentCursorPage(cm.getCursor());});
|
||||||
this.codeEditor.current.codeMirror.on('scroll', _.throttle(()=>{this.updateCurrentViewPage(this.codeEditor.current.getTopVisibleLine())}, 200));
|
this.codeEditor.current.codeMirror.on('scroll', _.throttle(()=>{this.updateCurrentViewPage(this.codeEditor.current.getTopVisibleLine());}, 200));
|
||||||
|
|
||||||
const editorTheme = window.localStorage.getItem(EDITOR_THEME_KEY);
|
const editorTheme = window.localStorage.getItem(EDITOR_THEME_KEY);
|
||||||
if(editorTheme) {
|
if(editorTheme) {
|
||||||
@@ -109,9 +109,9 @@ const Editor = createClass({
|
|||||||
if(!(e.ctrlKey && e.metaKey && e.shiftKey)) return;
|
if(!(e.ctrlKey && e.metaKey && e.shiftKey)) return;
|
||||||
const LEFTARROW_KEY = 37;
|
const LEFTARROW_KEY = 37;
|
||||||
const RIGHTARROW_KEY = 39;
|
const RIGHTARROW_KEY = 39;
|
||||||
if (e.keyCode == RIGHTARROW_KEY) this.brewJump();
|
if(e.keyCode == RIGHTARROW_KEY) this.brewJump();
|
||||||
if (e.keyCode == LEFTARROW_KEY) this.sourceJump();
|
if(e.keyCode == LEFTARROW_KEY) this.sourceJump();
|
||||||
if (e.keyCode == LEFTARROW_KEY || e.keyCode == RIGHTARROW_KEY) {
|
if(e.keyCode == LEFTARROW_KEY || e.keyCode == RIGHTARROW_KEY) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
@@ -128,14 +128,14 @@ const Editor = createClass({
|
|||||||
updateCurrentCursorPage : function(cursor) {
|
updateCurrentCursorPage : function(cursor) {
|
||||||
const lines = this.props.brew.text.split('\n').slice(0, cursor.line + 1);
|
const lines = this.props.brew.text.split('\n').slice(0, cursor.line + 1);
|
||||||
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
|
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
|
||||||
const currentPage = lines.reduce((count, line) => count + (pageRegex.test(line) ? 1 : 0), 1);
|
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
|
||||||
this.props.onCursorPageChange(currentPage);
|
this.props.onCursorPageChange(currentPage);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateCurrentViewPage : function(topScrollLine) {
|
updateCurrentViewPage : function(topScrollLine) {
|
||||||
const lines = this.props.brew.text.split('\n').slice(0, topScrollLine + 1);
|
const lines = this.props.brew.text.split('\n').slice(0, topScrollLine + 1);
|
||||||
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
|
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
|
||||||
const currentPage = lines.reduce((count, line) => count + (pageRegex.test(line) ? 1 : 0), 1);
|
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
|
||||||
this.props.onViewPageChange(currentPage);
|
this.props.onViewPageChange(currentPage);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -322,10 +322,10 @@ const Editor = createClass({
|
|||||||
const currentPos = brewRenderer.scrollTop;
|
const currentPos = brewRenderer.scrollTop;
|
||||||
const targetPos = window.frames['BrewRenderer'].contentDocument.getElementById(`p${targetPage}`).getBoundingClientRect().top;
|
const targetPos = window.frames['BrewRenderer'].contentDocument.getElementById(`p${targetPage}`).getBoundingClientRect().top;
|
||||||
|
|
||||||
const checkIfScrollComplete = () => {
|
const checkIfScrollComplete = ()=>{
|
||||||
let scrollingTimeout;
|
let scrollingTimeout;
|
||||||
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
|
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
|
||||||
scrollingTimeout = setTimeout(() => {
|
scrollingTimeout = setTimeout(()=>{
|
||||||
isJumping = false;
|
isJumping = false;
|
||||||
brewRenderer.removeEventListener('scroll', checkIfScrollComplete);
|
brewRenderer.removeEventListener('scroll', checkIfScrollComplete);
|
||||||
}, 150); // If 150 ms pass without a brewRenderer scroll event, assume scrolling is done
|
}, 150); // If 150 ms pass without a brewRenderer scroll event, assume scrolling is done
|
||||||
@@ -364,16 +364,16 @@ const Editor = createClass({
|
|||||||
|
|
||||||
let currentY = this.codeEditor.current.codeMirror.getScrollInfo().top;
|
let currentY = this.codeEditor.current.codeMirror.getScrollInfo().top;
|
||||||
let targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
|
let targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
|
||||||
|
|
||||||
const checkIfScrollComplete = () => {
|
const checkIfScrollComplete = ()=>{
|
||||||
let scrollingTimeout;
|
let scrollingTimeout;
|
||||||
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
|
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
|
||||||
scrollingTimeout = setTimeout(() => {
|
scrollingTimeout = setTimeout(()=>{
|
||||||
isJumping = false;
|
isJumping = false;
|
||||||
this.codeEditor.current.codeMirror.off('scroll', checkIfScrollComplete);
|
this.codeEditor.current.codeMirror.off('scroll', checkIfScrollComplete);
|
||||||
}, 150); // If 150 ms pass without a scroll event, assume scrolling is done
|
}, 150); // If 150 ms pass without a scroll event, assume scrolling is done
|
||||||
};
|
};
|
||||||
|
|
||||||
isJumping = true;
|
isJumping = true;
|
||||||
checkIfScrollComplete();
|
checkIfScrollComplete();
|
||||||
this.codeEditor.current.codeMirror.on('scroll', checkIfScrollComplete);
|
this.codeEditor.current.codeMirror.on('scroll', checkIfScrollComplete);
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ const ErrorNavItem = createClass({
|
|||||||
Looks like there was a problem retreiving
|
Looks like there was a problem retreiving
|
||||||
the theme, or a theme that it inherits,
|
the theme, or a theme that it inherits,
|
||||||
for this brew. Verify that brew <a className='lowercase' target='_blank' rel='noopener noreferrer' href={`/share/${response.body.brewId}`}>
|
for this brew. Verify that brew <a className='lowercase' target='_blank' rel='noopener noreferrer' href={`/share/${response.body.brewId}`}>
|
||||||
{response.body.brewId}</a> still exists!
|
{response.body.brewId}</a> still exists!
|
||||||
</div>
|
</div>
|
||||||
</Nav.item>;
|
</Nav.item>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ const VaultPage = (props)=>{
|
|||||||
|
|
||||||
if(error) {
|
if(error) {
|
||||||
const errorText = ErrorIndex()[error.HBErrorCode.toString()] || '';
|
const errorText = ErrorIndex()[error.HBErrorCode.toString()] || '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='foundBrews noBrews'>
|
<div className='foundBrews noBrews'>
|
||||||
<h3>Error: {errorText}</h3>
|
<h3>Error: {errorText}</h3>
|
||||||
|
|||||||
11
package-lock.json
generated
11
package-lock.json
generated
@@ -25,7 +25,7 @@
|
|||||||
"expr-eval": "^2.0.2",
|
"expr-eval": "^2.0.2",
|
||||||
"express": "^4.21.0",
|
"express": "^4.21.0",
|
||||||
"express-async-handler": "^1.2.0",
|
"express-async-handler": "^1.2.0",
|
||||||
"express-static-gzip": "2.1.7",
|
"express-static-gzip": "2.1.8",
|
||||||
"fs-extra": "11.2.0",
|
"fs-extra": "11.2.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jwt-simple": "^0.5.6",
|
"jwt-simple": "^0.5.6",
|
||||||
@@ -6362,12 +6362,11 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/express-static-gzip": {
|
"node_modules/express-static-gzip": {
|
||||||
"version": "2.1.7",
|
"version": "2.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.8.tgz",
|
||||||
"integrity": "sha512-QOCZUC+lhPPCjIJKpQGu1Oa61Axg9Mq09Qvit8Of7kzpMuwDeMSqjjQteQS3OVw/GkENBoSBheuQDWPlngImvw==",
|
"integrity": "sha512-g8tiJuI9Y9Ffy59ehVXvqb0hhP83JwZiLxzanobPaMbkB5qBWA8nuVgd+rcd5qzH3GkgogTALlc0BaADYwnMbQ==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"serve-static": "^1.14.1"
|
"serve-static": "^1.16.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express/node_modules/cookie": {
|
"node_modules/express/node_modules/cookie": {
|
||||||
|
|||||||
@@ -100,7 +100,7 @@
|
|||||||
"expr-eval": "^2.0.2",
|
"expr-eval": "^2.0.2",
|
||||||
"express": "^4.21.0",
|
"express": "^4.21.0",
|
||||||
"express-async-handler": "^1.2.0",
|
"express-async-handler": "^1.2.0",
|
||||||
"express-static-gzip": "2.1.7",
|
"express-static-gzip": "2.1.8",
|
||||||
"fs-extra": "11.2.0",
|
"fs-extra": "11.2.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jwt-simple": "^0.5.6",
|
"jwt-simple": "^0.5.6",
|
||||||
|
|||||||
@@ -934,7 +934,7 @@ brew`);
|
|||||||
expect(req.brew).toEqual(testBrew);
|
expect(req.brew).toEqual(testBrew);
|
||||||
expect(req.brew).toHaveProperty('style', '\nI Have a style!\n');
|
expect(req.brew).toHaveProperty('style', '\nI Have a style!\n');
|
||||||
expect(res.status).toHaveBeenCalledWith(200);
|
expect(res.status).toHaveBeenCalledWith(200);
|
||||||
expect(res.send).toHaveBeenCalledWith("\nI Have a style!\n");
|
expect(res.send).toHaveBeenCalledWith('\nI Have a style!\n');
|
||||||
expect(res.set).toHaveBeenCalledWith({
|
expect(res.set).toHaveBeenCalledWith({
|
||||||
'Cache-Control' : 'no-cache',
|
'Cache-Control' : 'no-cache',
|
||||||
'Content-Type' : 'text/css'
|
'Content-Type' : 'text/css'
|
||||||
|
|||||||
@@ -49,12 +49,12 @@ const CodeEditor = createClass({
|
|||||||
displayName : 'CodeEditor',
|
displayName : 'CodeEditor',
|
||||||
getDefaultProps : function() {
|
getDefaultProps : function() {
|
||||||
return {
|
return {
|
||||||
language : '',
|
language : '',
|
||||||
value : '',
|
value : '',
|
||||||
wrap : true,
|
wrap : true,
|
||||||
onChange : ()=>{},
|
onChange : ()=>{},
|
||||||
enableFolding : true,
|
enableFolding : true,
|
||||||
editorTheme : 'default'
|
editorTheme : 'default'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ const CodeEditor = createClass({
|
|||||||
autoCompleteEmoji.showAutocompleteEmoji(CodeMirror, this.codeMirror);
|
autoCompleteEmoji.showAutocompleteEmoji(CodeMirror, this.codeMirror);
|
||||||
|
|
||||||
// Note: codeMirror passes a copy of itself in this callback. cm === this.codeMirror. Either one works.
|
// Note: codeMirror passes a copy of itself in this callback. cm === this.codeMirror. Either one works.
|
||||||
this.codeMirror.on('change', (cm)=>{this.props.onChange(cm.getValue())});
|
this.codeMirror.on('change', (cm)=>{this.props.onChange(cm.getValue());});
|
||||||
this.updateSize();
|
this.updateSize();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -399,7 +399,7 @@ const CodeEditor = createClass({
|
|||||||
},
|
},
|
||||||
getTopVisibleLine : function(){
|
getTopVisibleLine : function(){
|
||||||
const rect = this.codeMirror.getWrapperElement().getBoundingClientRect();
|
const rect = this.codeMirror.getWrapperElement().getBoundingClientRect();
|
||||||
const topVisibleLine = this.codeMirror.lineAtHeight(rect.top, "window");
|
const topVisibleLine = this.codeMirror.lineAtHeight(rect.top, 'window');
|
||||||
return topVisibleLine;
|
return topVisibleLine;
|
||||||
},
|
},
|
||||||
updateSize : function(){
|
updateSize : function(){
|
||||||
|
|||||||
@@ -105,16 +105,16 @@ renderer.link = function (href, title, text) {
|
|||||||
// Expose `src` attribute as `--HB_src` to make the URL accessible via CSS
|
// Expose `src` attribute as `--HB_src` to make the URL accessible via CSS
|
||||||
renderer.image = function (href, title, text) {
|
renderer.image = function (href, title, text) {
|
||||||
href = cleanUrl(href);
|
href = cleanUrl(href);
|
||||||
if (href === null)
|
if(href === null)
|
||||||
return text;
|
return text;
|
||||||
|
|
||||||
let out = `<img src="${href}" alt="${text}" style="--HB_src:url(${href});"`;
|
let out = `<img src="${href}" alt="${text}" style="--HB_src:url(${href});"`;
|
||||||
if (title)
|
if(title)
|
||||||
out += ` title="${title}"`;
|
out += ` title="${title}"`;
|
||||||
|
|
||||||
out += '>';
|
out += '>';
|
||||||
return out;
|
return out;
|
||||||
}
|
};
|
||||||
|
|
||||||
// Disable default reflink behavior, as it steps on our variables extension
|
// Disable default reflink behavior, as it steps on our variables extension
|
||||||
tokenizer.def = function () {
|
tokenizer.def = function () {
|
||||||
@@ -745,7 +745,7 @@ const tableTerminators = [
|
|||||||
`:+\\n`, // hardBreak
|
`:+\\n`, // hardBreak
|
||||||
` *{[^\n]+}`, // blockInjector
|
` *{[^\n]+}`, // blockInjector
|
||||||
` *{{[^{\n]*\n.*?\n}}` // mustacheDiv
|
` *{{[^{\n]*\n.*?\n}}` // mustacheDiv
|
||||||
]
|
];
|
||||||
|
|
||||||
Marked.use(MarkedVariables());
|
Marked.use(MarkedVariables());
|
||||||
Marked.use({ extensions : [definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks, superSubScripts,
|
Marked.use({ extensions : [definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks, superSubScripts,
|
||||||
@@ -755,12 +755,12 @@ Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false });
|
|||||||
Marked.use(MarkedExtendedTables(tableTerminators), MarkedGFMHeadingId({ globalSlugs: true }), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions));
|
Marked.use(MarkedExtendedTables(tableTerminators), MarkedGFMHeadingId({ globalSlugs: true }), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions));
|
||||||
|
|
||||||
function cleanUrl(href) {
|
function cleanUrl(href) {
|
||||||
try {
|
try {
|
||||||
href = encodeURI(href).replace(/%25/g, '%');
|
href = encodeURI(href).replace(/%25/g, '%');
|
||||||
} catch {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return href;
|
return href;
|
||||||
}
|
}
|
||||||
|
|
||||||
const escapeTest = /[&<>"']/;
|
const escapeTest = /[&<>"']/;
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ const SplitPane = createClass({
|
|||||||
|
|
||||||
getInitialState : function() {
|
getInitialState : function() {
|
||||||
return {
|
return {
|
||||||
currentDividerPos : null,
|
currentDividerPos : null,
|
||||||
windowWidth : 0,
|
windowWidth : 0,
|
||||||
isDragging : false,
|
isDragging : false,
|
||||||
moveSource : false,
|
moveSource : false,
|
||||||
moveBrew : false,
|
moveBrew : false,
|
||||||
showMoveArrows : true
|
showMoveArrows : true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ const SplitPane = createClass({
|
|||||||
|
|
||||||
// This lives here instead of in the initial render because you cannot touch localStorage until the componant mounts.
|
// This lives here instead of in the initial render because you cannot touch localStorage until the componant mounts.
|
||||||
const loadLiveScroll = window.localStorage.getItem('liveScroll') === 'true';
|
const loadLiveScroll = window.localStorage.getItem('liveScroll') === 'true';
|
||||||
this.setState({ liveScroll : loadLiveScroll });
|
this.setState({ liveScroll: loadLiveScroll });
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount : function() {
|
componentWillUnmount : function() {
|
||||||
@@ -130,7 +130,7 @@ const SplitPane = createClass({
|
|||||||
<i className='fas fa-arrow-right' />
|
<i className='fas fa-arrow-right' />
|
||||||
</div>
|
</div>
|
||||||
<div id='scrollToggleDiv' className={this.state.liveScroll ? 'arrow lock' : 'arrow unlock'}
|
<div id='scrollToggleDiv' className={this.state.liveScroll ? 'arrow lock' : 'arrow unlock'}
|
||||||
style={{ left: this.state.currentDividerPos-4 }}
|
style={{ left: this.state.currentDividerPos-4 }}
|
||||||
onClick={this.liveScrollToggle} >
|
onClick={this.liveScrollToggle} >
|
||||||
<i id='scrollToggle' className={this.state.liveScroll ? 'fas fa-lock' : 'fas fa-unlock'} />
|
<i id='scrollToggle' className={this.state.liveScroll ? 'fas fa-lock' : 'fas fa-unlock'} />
|
||||||
</div>
|
</div>
|
||||||
@@ -160,7 +160,7 @@ const SplitPane = createClass({
|
|||||||
...(this.props.showDividerButtons && {
|
...(this.props.showDividerButtons && {
|
||||||
moveBrew : this.state.moveBrew,
|
moveBrew : this.state.moveBrew,
|
||||||
moveSource : this.state.moveSource,
|
moveSource : this.state.moveSource,
|
||||||
liveScroll : this.state.liveScroll,
|
liveScroll : this.state.liveScroll,
|
||||||
setMoveArrows : this.setMoveArrows,
|
setMoveArrows : this.setMoveArrows,
|
||||||
}),
|
}),
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ const dedent = require('dedent-tabs').default;
|
|||||||
const mapPages = (pages)=>{
|
const mapPages = (pages)=>{
|
||||||
let actualPage = 0;
|
let actualPage = 0;
|
||||||
let mappedPage = 0; // Number displayed in footer
|
let mappedPage = 0; // Number displayed in footer
|
||||||
let pageMap = [];
|
const pageMap = [];
|
||||||
|
|
||||||
pages.forEach(page => {
|
pages.forEach((page)=>{
|
||||||
actualPage++;
|
actualPage++;
|
||||||
const doSkip = page.querySelector('.skipCounting');
|
const doSkip = page.querySelector('.skipCounting');
|
||||||
const doReset = page.querySelector('.resetCounting');
|
const doReset = page.querySelector('.resetCounting');
|
||||||
@@ -24,13 +24,13 @@ const mapPages = (pages)=>{
|
|||||||
return pageMap;
|
return pageMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getMarkdown = (headings, pageMap) => {
|
const getMarkdown = (headings, pageMap)=>{
|
||||||
const levelPad = ['- ###', ' - ####', ' -', ' -', ' -', ' -'];
|
const levelPad = ['- ###', ' - ####', ' -', ' -', ' -', ' -'];
|
||||||
|
|
||||||
let allMarkdown = [];
|
|
||||||
let depthChain = [0];
|
|
||||||
|
|
||||||
headings.forEach(heading => {
|
const allMarkdown = [];
|
||||||
|
const depthChain = [0];
|
||||||
|
|
||||||
|
headings.forEach((heading)=>{
|
||||||
const page = parseInt(heading.closest('.page').id?.replace(/^p/, ''));
|
const page = parseInt(heading.closest('.page').id?.replace(/^p/, ''));
|
||||||
const mappedPage = pageMap[page].mappedPage;
|
const mappedPage = pageMap[page].mappedPage;
|
||||||
const showPage = pageMap[page].showPage;
|
const showPage = pageMap[page].showPage;
|
||||||
@@ -42,14 +42,14 @@ const getMarkdown = (headings, pageMap) => {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//If different header depth than last, remove indents until nearest higher-level header, then indent once
|
//If different header depth than last, remove indents until nearest higher-level header, then indent once
|
||||||
if (depth !== depthChain[depthChain.length -1]) {
|
if(depth !== depthChain[depthChain.length -1]) {
|
||||||
while (depth <= depthChain[depthChain.length - 1]) {
|
while (depth <= depthChain[depthChain.length - 1]) {
|
||||||
depthChain.pop();
|
depthChain.pop();
|
||||||
}
|
}
|
||||||
depthChain.push(depth);
|
depthChain.push(depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
let markdown = `${levelPad[depthChain.length - 2]} [{{ ${title}}}{{ ${mappedPage}}}](#p${page})`;
|
const markdown = `${levelPad[depthChain.length - 2]} [{{ ${title}}}{{ ${mappedPage}}}](#p${page})`;
|
||||||
allMarkdown.push(markdown);
|
allMarkdown.push(markdown);
|
||||||
});
|
});
|
||||||
return allMarkdown.join('\n');
|
return allMarkdown.join('\n');
|
||||||
|
|||||||
Reference in New Issue
Block a user