mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-08 11:52:44 +00:00
Merge pull request #4004 from naturalcrit/altpageattributes
Alternate \page{curlies}
This commit is contained in:
@@ -17,10 +17,9 @@ const dedent = require('dedent-tabs').default;
|
|||||||
const { printCurrentBrew } = require('../../../shared/helpers.js');
|
const { printCurrentBrew } = require('../../../shared/helpers.js');
|
||||||
|
|
||||||
import HeaderNav from './headerNav/headerNav.jsx';
|
import HeaderNav from './headerNav/headerNav.jsx';
|
||||||
|
|
||||||
import { safeHTML } from './safeHTML.js';
|
import { safeHTML } from './safeHTML.js';
|
||||||
|
|
||||||
|
const PAGEBREAK_REGEX_V3 = /^(?=\\page(?: *{[^\n{}]*})?$)/m;
|
||||||
const PAGE_HEIGHT = 1056;
|
const PAGE_HEIGHT = 1056;
|
||||||
|
|
||||||
const INITIAL_CONTENT = dedent`
|
const INITIAL_CONTENT = dedent`
|
||||||
@@ -78,7 +77,7 @@ const BrewPage = (props)=>{
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return <div className={props.className} id={`p${props.index + 1}`} data-index={props.index} ref={pageRef} style={props.style}>
|
return <div className={props.className} id={`p${props.index + 1}`} data-index={props.index} ref={pageRef} style={props.style} {...props.attributes}>
|
||||||
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: cleanText }} />
|
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: cleanText }} />
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
@@ -126,7 +125,7 @@ const BrewRenderer = (props)=>{
|
|||||||
if(props.renderer == 'legacy') {
|
if(props.renderer == 'legacy') {
|
||||||
rawPages = props.text.split('\\page');
|
rawPages = props.text.split('\\page');
|
||||||
} else {
|
} else {
|
||||||
rawPages = props.text.split(/^\\page$/gm);
|
rawPages = props.text.split(PAGEBREAK_REGEX_V3);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePageVisibilityChange = (pageNum, isVisible, isCenter)=>{
|
const handlePageVisibilityChange = (pageNum, isVisible, isCenter)=>{
|
||||||
@@ -173,20 +172,34 @@ const BrewRenderer = (props)=>{
|
|||||||
|
|
||||||
const renderPage = (pageText, index)=>{
|
const renderPage = (pageText, index)=>{
|
||||||
|
|
||||||
const styles = {
|
let styles = {
|
||||||
...(!displayOptions.pageShadows ? { boxShadow: 'none' } : {})
|
...(!displayOptions.pageShadows ? { boxShadow: 'none' } : {})
|
||||||
// Add more conditions as needed
|
// Add more conditions as needed
|
||||||
};
|
};
|
||||||
|
let classes = 'page';
|
||||||
|
let attributes = {};
|
||||||
|
|
||||||
if(props.renderer == 'legacy') {
|
if(props.renderer == 'legacy') {
|
||||||
const html = MarkdownLegacy.render(pageText);
|
const html = MarkdownLegacy.render(pageText);
|
||||||
|
|
||||||
return <BrewPage className='page phb' index={index} key={index} contents={html} style={styles} onVisibilityChange={handlePageVisibilityChange} />;
|
return <BrewPage className='page phb' index={index} key={index} contents={html} style={styles} onVisibilityChange={handlePageVisibilityChange} />;
|
||||||
} else {
|
} else {
|
||||||
|
if(pageText.startsWith('\\page')) {
|
||||||
|
const firstLineTokens = Markdown.marked.lexer(pageText.split('\n', 1)[0])[0].tokens;
|
||||||
|
const injectedTags = firstLineTokens.find((obj)=>obj.injectedTags !== undefined)?.injectedTags;
|
||||||
|
if(injectedTags) {
|
||||||
|
styles = { ...styles, ...injectedTags.styles };
|
||||||
|
styles = _.mapKeys(styles, (v, k) => k.startsWith('--') ? k : _.camelCase(k)); // Convert CSS to camelCase for React
|
||||||
|
classes = [classes, injectedTags.classes].join(' ').trim();
|
||||||
|
attributes = injectedTags.attributes;
|
||||||
|
}
|
||||||
|
pageText = pageText.includes('\n') ? pageText.substring(pageText.indexOf('\n') + 1) : ''; // Remove the \page line
|
||||||
|
}
|
||||||
|
|
||||||
pageText += `\n\n \n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
|
pageText += `\n\n \n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
|
||||||
const html = Markdown.render(pageText, index);
|
const html = Markdown.render(pageText, index);
|
||||||
|
|
||||||
return <BrewPage className='page' index={index} key={index} contents={html} style={styles} onVisibilityChange={handlePageVisibilityChange} />;
|
return <BrewPage className={classes} index={index} key={index} contents={html} style={styles} attributes={attributes} onVisibilityChange={handlePageVisibilityChange} />;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ const MetadataEditor = require('./metadataEditor/metadataEditor.jsx');
|
|||||||
|
|
||||||
const EDITOR_THEME_KEY = 'HOMEBREWERY-EDITOR-THEME';
|
const EDITOR_THEME_KEY = 'HOMEBREWERY-EDITOR-THEME';
|
||||||
|
|
||||||
const SNIPPETBAR_HEIGHT = 25;
|
const PAGEBREAK_REGEX_V3 = /^(?=\\page(?: *{[^\n{}]*})?$)/m;
|
||||||
|
const SNIPPETBAR_HEIGHT = 25;
|
||||||
const DEFAULT_STYLE_TEXT = dedent`
|
const DEFAULT_STYLE_TEXT = dedent`
|
||||||
/*=======--- Example CSS styling ---=======*/
|
/*=======--- Example CSS styling ---=======*/
|
||||||
/* Any CSS here will apply to your document! */
|
/* Any CSS here will apply to your document! */
|
||||||
@@ -126,15 +127,15 @@ 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(1, cursor.line + 1);
|
||||||
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
|
const pageRegex = this.props.brew.renderer == 'V3' ? PAGEBREAK_REGEX_V3 : /\\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(1, topScrollLine + 1);
|
||||||
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
|
const pageRegex = this.props.brew.renderer == 'V3' ? PAGEBREAK_REGEX_V3 : /\\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);
|
||||||
},
|
},
|
||||||
@@ -174,7 +175,7 @@ const Editor = createClass({
|
|||||||
|
|
||||||
for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear();
|
for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear();
|
||||||
|
|
||||||
let editorPageCount = 2; // start page count from page 2
|
let editorPageCount = 1; // start page count from page 1
|
||||||
|
|
||||||
_.forEach(this.props.brew.text.split('\n'), (line, lineNumber)=>{
|
_.forEach(this.props.brew.text.split('\n'), (line, lineNumber)=>{
|
||||||
|
|
||||||
@@ -190,7 +191,10 @@ const Editor = createClass({
|
|||||||
|
|
||||||
// Styling for \page breaks
|
// Styling for \page breaks
|
||||||
if((this.props.renderer == 'legacy' && line.includes('\\page')) ||
|
if((this.props.renderer == 'legacy' && line.includes('\\page')) ||
|
||||||
(this.props.renderer == 'V3' && line.match(/^\\page$/))) {
|
(this.props.renderer == 'V3' && line.match(PAGEBREAK_REGEX_V3))) {
|
||||||
|
|
||||||
|
if(lineNumber > 0) // Since \page is optional on first line of document,
|
||||||
|
editorPageCount += 1; // don't use it to increment page count; stay at 1
|
||||||
|
|
||||||
// add back the original class 'background' but also add the new class '.pageline'
|
// add back the original class 'background' but also add the new class '.pageline'
|
||||||
codeMirror.addLineClass(lineNumber, 'background', 'pageLine');
|
codeMirror.addLineClass(lineNumber, 'background', 'pageLine');
|
||||||
@@ -199,8 +203,6 @@ const Editor = createClass({
|
|||||||
textContent : editorPageCount
|
textContent : editorPageCount
|
||||||
});
|
});
|
||||||
codeMirror.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement);
|
codeMirror.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement);
|
||||||
|
|
||||||
editorPageCount += 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// New Codemirror styling for V3 renderer
|
// New Codemirror styling for V3 renderer
|
||||||
@@ -358,7 +360,7 @@ const Editor = createClass({
|
|||||||
if(!this.isText() || isJumping)
|
if(!this.isText() || isJumping)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const textSplit = this.props.renderer == 'V3' ? /^\\page$/gm : /\\page/;
|
const textSplit = this.props.renderer == 'V3' ? PAGEBREAK_REGEX_V3 : /\\page/;
|
||||||
const textString = this.props.brew.text.split(textSplit).slice(0, targetPage-1).join(textSplit);
|
const textString = this.props.brew.text.split(textSplit).slice(0, targetPage-1).join(textSplit);
|
||||||
const targetLine = textString.match('\n') ? textString.split('\n').length - 1 : -1;
|
const targetLine = textString.match('\n') ? textString.split('\n').length - 1 : -1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user