mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-28 11:22:39 +00:00
Merge branch 'master' into addEditorThemes-#362
This commit is contained in:
@@ -11,6 +11,7 @@ const template = async function(name, title='', props = {}){
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, height=device-height, interactive-widget=resizes-visual" />
|
||||
<link href="//use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet" />
|
||||
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
|
||||
<link href=${`/${name}/bundle.css`} rel='stylesheet' />
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -35,7 +35,7 @@
|
||||
"marked-smartypants-lite": "^1.0.0",
|
||||
"markedLegacy": "npm:marked@^0.3.19",
|
||||
"moment": "^2.29.4",
|
||||
"mongoose": "^7.4.1",
|
||||
"mongoose": "^7.4.2",
|
||||
"nanoid": "3.3.4",
|
||||
"nconf": "^0.12.0",
|
||||
"npm": "^9.8.1",
|
||||
@@ -10204,9 +10204,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mongoose": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.4.1.tgz",
|
||||
"integrity": "sha512-o3E5KHHiHdaiwCJG3+9r70sncRKki71Ktf/TfXdW6myu+53rtZ56uLl5ylkQiCf60V3COJuOeekcxXVsjQ7cBA==",
|
||||
"version": "7.4.2",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.4.2.tgz",
|
||||
"integrity": "sha512-sNolW2hyncwvWmZjIEIwAckjaSKtC1SE86zE1v2TKm3vPTRogZfBQf+3zLYYdrgrVTzoaoICieVpct9hjcn3EQ==",
|
||||
"dependencies": {
|
||||
"bson": "^5.4.0",
|
||||
"kareem": "2.5.1",
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
"marked-smartypants-lite": "^1.0.0",
|
||||
"markedLegacy": "npm:marked@^0.3.19",
|
||||
"moment": "^2.29.4",
|
||||
"mongoose": "^7.4.1",
|
||||
"mongoose": "^7.4.2",
|
||||
"nanoid": "3.3.4",
|
||||
"nconf": "^0.12.0",
|
||||
"npm": "^9.8.1",
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
}
|
||||
|
||||
.codeEditor{
|
||||
@media screen and (pointer : coarse) {
|
||||
font-size : 16px;
|
||||
}
|
||||
.CodeMirror-foldmarker {
|
||||
font-family: inherit;
|
||||
text-shadow: none;
|
||||
|
||||
@@ -61,7 +61,8 @@ const SplitPane = createClass({
|
||||
return result;
|
||||
},
|
||||
|
||||
handleUp : function(){
|
||||
handleUp : function(e){
|
||||
e.preventDefault();
|
||||
if(this.state.isDragging){
|
||||
this.props.onDragFinish(this.state.currentDividerPos);
|
||||
window.localStorage.setItem(this.props.storageKey, this.state.currentDividerPos);
|
||||
@@ -76,6 +77,7 @@ const SplitPane = createClass({
|
||||
},
|
||||
|
||||
handleMove : function(e){
|
||||
e.preventDefault();
|
||||
if(!this.state.isDragging) return;
|
||||
|
||||
const newSize = this.limitPosition(e.pageX);
|
||||
@@ -122,7 +124,7 @@ const SplitPane = createClass({
|
||||
renderDivider : function(){
|
||||
return <>
|
||||
{this.renderMoveArrows()}
|
||||
<div className='divider' onMouseDown={this.handleDown} >
|
||||
<div className='divider' onPointerDown={this.handleDown} >
|
||||
<div className='dots'>
|
||||
<i className='fas fa-circle' />
|
||||
<i className='fas fa-circle' />
|
||||
@@ -133,7 +135,7 @@ const SplitPane = createClass({
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return <div className='splitPane' onMouseMove={this.handleMove} onMouseUp={this.handleUp}>
|
||||
return <div className='splitPane' onPointerMove={this.handleMove} onPointerUp={this.handleUp}>
|
||||
<Pane
|
||||
ref='pane1'
|
||||
width={this.state.currentDividerPos}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
flex : 1;
|
||||
}
|
||||
.divider{
|
||||
touch-action : none;
|
||||
display : table;
|
||||
height : 100%;
|
||||
width : 15px;
|
||||
|
||||
@@ -220,34 +220,51 @@ module.exports = [
|
||||
view : 'text',
|
||||
snippets : [
|
||||
{
|
||||
name : 'Class Table',
|
||||
icon : 'fas fa-table',
|
||||
gen : ClassTableGen.full('classTable,frame,decoration,wide'),
|
||||
},
|
||||
{
|
||||
name : 'Class Table (unframed)',
|
||||
icon : 'fas fa-border-none',
|
||||
gen : ClassTableGen.full('classTable,wide'),
|
||||
},
|
||||
{
|
||||
name : '1/2 Class Table',
|
||||
icon : 'fas fa-list-alt',
|
||||
gen : ClassTableGen.half('classTable,decoration,frame'),
|
||||
},
|
||||
{
|
||||
name : '1/2 Class Table (unframed)',
|
||||
icon : 'fas fa-border-none',
|
||||
gen : ClassTableGen.half('classTable'),
|
||||
},
|
||||
{
|
||||
name : '1/3 Class Table',
|
||||
icon : 'fas fa-border-all',
|
||||
gen : ClassTableGen.third('classTable,frame'),
|
||||
},
|
||||
{
|
||||
name : '1/3 Class Table (unframed)',
|
||||
icon : 'fas fa-border-none',
|
||||
gen : ClassTableGen.third('classTable'),
|
||||
name : 'Class Tables',
|
||||
icon : 'fas fa-table',
|
||||
gen : ClassTableGen.full('classTable,frame,decoration,wide'),
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Martial Class Table',
|
||||
icon : 'fas fa-table',
|
||||
gen : ClassTableGen.non('classTable,frame,decoration'),
|
||||
},
|
||||
{
|
||||
name : 'Martial Class Table (unframed)',
|
||||
icon : 'fas fa-border-none',
|
||||
gen : ClassTableGen.non('classTable'),
|
||||
},
|
||||
{
|
||||
name : 'Full Caster Class Table',
|
||||
icon : 'fas fa-table',
|
||||
gen : ClassTableGen.full('classTable,frame,decoration,wide'),
|
||||
},
|
||||
{
|
||||
name : 'Full Caster Class Table (unframed)',
|
||||
icon : 'fas fa-border-none',
|
||||
gen : ClassTableGen.full('classTable,wide'),
|
||||
},
|
||||
{
|
||||
name : 'Half Caster Class Table',
|
||||
icon : 'fas fa-list-alt',
|
||||
gen : ClassTableGen.half('classTable,frame,decoration,wide'),
|
||||
},
|
||||
{
|
||||
name : 'Half Caster Class Table (unframed)',
|
||||
icon : 'fas fa-border-none',
|
||||
gen : ClassTableGen.half('classTable,wide'),
|
||||
},
|
||||
{
|
||||
name : 'Third Caster Spell Table',
|
||||
icon : 'fas fa-border-all',
|
||||
gen : ClassTableGen.third('classTable,frame,decoration'),
|
||||
},
|
||||
{
|
||||
name : 'Third Caster Spell Table (unframed)',
|
||||
icon : 'fas fa-border-none',
|
||||
gen : ClassTableGen.third('classTable'),
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'Rune Table',
|
||||
|
||||
@@ -1,132 +1,138 @@
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const features = [
|
||||
'Astrological Botany',
|
||||
'Biochemical Sorcery',
|
||||
'Civil Divination',
|
||||
'Consecrated Augury',
|
||||
'Demonic Anthropology',
|
||||
'Divinatory Mineralogy',
|
||||
'Exo Interfacer',
|
||||
'Genetic Banishing',
|
||||
'Gunpowder Torturer',
|
||||
'Gunslinger Corruptor',
|
||||
'Hermetic Geography',
|
||||
'Immunological Cultist',
|
||||
'Malefic Chemist',
|
||||
'Mathematical Pharmacy',
|
||||
'Nuclear Biochemistry',
|
||||
'Orbital Gravedigger',
|
||||
'Pharmaceutical Outlaw',
|
||||
'Phased Linguist',
|
||||
'Plasma Gunslinger',
|
||||
'Police Necromancer',
|
||||
'Ritual Astronomy',
|
||||
'Sixgun Poisoner',
|
||||
'Seismological Alchemy',
|
||||
'Spiritual Illusionism',
|
||||
'Statistical Occultism',
|
||||
'Spell Analyst',
|
||||
'Torque Interfacer'
|
||||
'Astrological Botany', 'Biochemical Sorcery', 'Civil Divination',
|
||||
'Consecrated Augury', 'Demonic Anthropology', 'Divinatory Mineralogy',
|
||||
'Exo Interfacer', 'Genetic Banishing', 'Gunpowder Torturer',
|
||||
'Gunslinger Corruptor', 'Hermetic Geography', 'Immunological Cultist',
|
||||
'Malefic Chemist', 'Mathematical Pharmacy', 'Nuclear Biochemistry',
|
||||
'Orbital Gravedigger', 'Pharmaceutical Outlaw', 'Phased Linguist',
|
||||
'Plasma Gunslinger', 'Police Necromancer', 'Ritual Astronomy',
|
||||
'Sixgun Poisoner', 'Seismological Alchemy', 'Spiritual Illusionism',
|
||||
'Statistical Occultism', 'Spell Analyst', 'Torque Interfacer'
|
||||
].map((f)=>_.padEnd(f, 21)); // Pad to equal length of 21 chars long
|
||||
|
||||
const classnames = [
|
||||
'Ackerman', 'Berserker-Typist', 'Concierge', 'Fishmonger',
|
||||
'Haberdasher', 'Manicurist', 'Netrunner', 'Weirkeeper'
|
||||
];
|
||||
|
||||
const classnames = ['Ackerman', 'Berserker-Typist', 'Concierge', 'Fishmonger',
|
||||
'Haberdasher', 'Manicurist', 'Netrunner', 'Weirkeeper'];
|
||||
|
||||
const levels = ['1st', '2nd', '3rd', '4th', '5th',
|
||||
'6th', '7th', '8th', '9th', '10th',
|
||||
'11th', '12th', '13th', '14th', '15th',
|
||||
'16th', '17th', '18th', '19th', '20th'];
|
||||
|
||||
const profBonus = [2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6];
|
||||
|
||||
const maxes = [4, 3, 3, 3, 3, 2, 2, 1, 1];
|
||||
|
||||
const drawSlots = function(Slots, rows, padding){
|
||||
let slots = Number(Slots);
|
||||
return _.times(rows, function(i){
|
||||
const max = maxes[i];
|
||||
if(slots < 1) return _.pad('—', padding);
|
||||
const res = _.min([max, slots]);
|
||||
slots -= res;
|
||||
return _.pad(res.toString(), padding);
|
||||
}).join(' | ');
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
full : function(classes){
|
||||
const classname = _.sample(classnames);
|
||||
|
||||
|
||||
let cantrips = 3;
|
||||
let spells = 1;
|
||||
let slots = 2;
|
||||
return `{{${classes}\n##### The ${classname}\n` +
|
||||
`| Level | Proficiency | Features | Cantrips | Spells | --- Spell Slots Per Spell Level ---|||||||||\n`+
|
||||
`| ^| Bonus ^| ^| Known ^| Known ^|1st |2nd |3rd |4th |5th |6th |7th |8th |9th |\n`+
|
||||
`|:-----:|:-----------:|:-------------|:--------:|:------:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|\n${
|
||||
_.map(levels, function(levelName, level){
|
||||
const res = [
|
||||
_.pad(levelName, 5),
|
||||
_.pad(`+${profBonus[level]}`, 2),
|
||||
_.padEnd(_.sample(features), 21),
|
||||
_.pad(cantrips.toString(), 8),
|
||||
_.pad(spells.toString(), 6),
|
||||
drawSlots(slots, 9, 2),
|
||||
].join(' | ');
|
||||
|
||||
cantrips += _.random(0, 1);
|
||||
spells += _.random(0, 1);
|
||||
slots += _.random(0, 2);
|
||||
|
||||
return `| ${res} |`;
|
||||
}).join('\n')}\n}}\n\n`;
|
||||
non : function(snippetClasses){
|
||||
return dedent`
|
||||
{{${snippetClasses}
|
||||
##### The ${_.sample(classnames)}
|
||||
| Level | Proficiency Bonus | Features | ${_.sample(features)} |
|
||||
|:-----:|:-----------------:|:---------|:---------------------:|
|
||||
| 1st | +2 | ${_.sample(features)} | 2 |
|
||||
| 2nd | +2 | ${_.sample(features)} | 2 |
|
||||
| 3rd | +2 | ${_.sample(features)} | 3 |
|
||||
| 4th | +2 | ${_.sample(features)} | 3 |
|
||||
| 5th | +3 | ${_.sample(features)} | 3 |
|
||||
| 6th | +3 | ${_.sample(features)} | 4 |
|
||||
| 7th | +3 | ${_.sample(features)} | 4 |
|
||||
| 8th | +3 | ${_.sample(features)} | 4 |
|
||||
| 9th | +4 | ${_.sample(features)} | 4 |
|
||||
| 10th | +4 | ${_.sample(features)} | 4 |
|
||||
| 11th | +4 | ${_.sample(features)} | 4 |
|
||||
| 12th | +4 | ${_.sample(features)} | 5 |
|
||||
| 13th | +5 | ${_.sample(features)} | 5 |
|
||||
| 14th | +5 | ${_.sample(features)} | 5 |
|
||||
| 15th | +5 | ${_.sample(features)} | 5 |
|
||||
| 16th | +5 | ${_.sample(features)} | 5 |
|
||||
| 17th | +6 | ${_.sample(features)} | 6 |
|
||||
| 18th | +6 | ${_.sample(features)} | 6 |
|
||||
| 19th | +6 | ${_.sample(features)} | 6 |
|
||||
| 20th | +6 | ${_.sample(features)} | unlimited |
|
||||
}}\n\n`;
|
||||
},
|
||||
|
||||
half : function(classes){
|
||||
const classname = _.sample(classnames);
|
||||
|
||||
let featureScore = 1;
|
||||
return `{{${classes}\n##### The ${classname}\n` +
|
||||
`| Level | Proficiency Bonus | Features | ${_.pad(_.sample(features), 21)} |\n` +
|
||||
`|:-----:|:-----------------:|:---------|:---------------------:|\n${
|
||||
_.map(levels, function(levelName, level){
|
||||
const res = [
|
||||
_.pad(levelName, 5),
|
||||
_.pad(`+${profBonus[level]}`, 2),
|
||||
_.padEnd(_.sample(features), 23),
|
||||
_.pad(`+${featureScore}`, 21),
|
||||
].join(' | ');
|
||||
|
||||
featureScore += _.random(0, 1);
|
||||
|
||||
return `| ${res} |`;
|
||||
}).join('\n')}\n}}\n\n`;
|
||||
full : function(snippetClasses){
|
||||
return dedent`
|
||||
{{${snippetClasses}
|
||||
##### The ${_.sample(classnames)}
|
||||
| Level | Proficiency | Features | Cantrips | --- Spell Slots Per Spell Level ---|||||||||
|
||||
| ^| Bonus ^| ^| Known ^|1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
|
||||
|:-----:|:-----------:|:-------------|:--------:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|
||||
| 1st | +2 | ${_.sample(features)} | 2 | 2 | — | — | — | — | — | — | — | — |
|
||||
| 2nd | +2 | ${_.sample(features)} | 2 | 3 | — | — | — | — | — | — | — | — |
|
||||
| 3rd | +2 | ${_.sample(features)} | 2 | 4 | 2 | — | — | — | — | — | — | — |
|
||||
| 4th | +2 | ${_.sample(features)} | 3 | 4 | 3 | — | — | — | — | — | — | — |
|
||||
| 5th | +3 | ${_.sample(features)} | 3 | 4 | 3 | 2 | — | — | — | — | — | — |
|
||||
| 6th | +3 | ${_.sample(features)} | 3 | 4 | 3 | 3 | — | — | — | — | — | — |
|
||||
| 7th | +3 | ${_.sample(features)} | 3 | 4 | 3 | 3 | 1 | — | — | — | — | — |
|
||||
| 8th | +3 | ${_.sample(features)} | 3 | 4 | 3 | 3 | 2 | — | — | — | — | — |
|
||||
| 9th | +4 | ${_.sample(features)} | 3 | 4 | 3 | 3 | 2 | 1 | — | — | — | — |
|
||||
| 10th | +4 | ${_.sample(features)} | 3 | 4 | 3 | 3 | 2 | 1 | — | — | — | — |
|
||||
| 11th | +4 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | — | — | — |
|
||||
| 12th | +4 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | — | — | — |
|
||||
| 13th | +5 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | — | — |
|
||||
| 14th | +5 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | — | — |
|
||||
| 15th | +5 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | 1 | — |
|
||||
| 16th | +5 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | 1 | — |
|
||||
| 17th | +6 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 2 | 1 | 1 | 1 | 1 | 1 |
|
||||
| 18th | +6 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 3 | 1 | 1 | 1 | 1 | 1 |
|
||||
| 19th | +6 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 3 | 2 | 2 | 1 | 1 | 1 |
|
||||
| 20th | +6 | ${_.sample(features)} | 4 | 4 | 3 | 3 | 3 | 2 | 2 | 2 | 1 | 1 |
|
||||
}}\n\n`;
|
||||
},
|
||||
|
||||
third : function(classes){
|
||||
const classname = _.sample(classnames);
|
||||
half : function(snippetClasses){
|
||||
return dedent`
|
||||
{{${snippetClasses}
|
||||
##### The ${_.sample(classnames)}
|
||||
| Level | Proficiency | Features | Spells |--- Spell Slots Per Spell Level ---|||||
|
||||
| ^| Bonus ^| ^| Known ^| 1st | 2nd | 3rd | 4th | 5th |
|
||||
|:-----:|:-----------:|:-------------|:------:|:-----:|:-----:|:-----:|:-----:|:-----:|
|
||||
| 1st | +2 | ${_.sample(features)} | — | — | — | — | — | — |
|
||||
| 2nd | +2 | ${_.sample(features)} | 2 | 2 | — | — | — | — |
|
||||
| 3rd | +2 | ${_.sample(features)} | 3 | 3 | — | — | — | — |
|
||||
| 4th | +2 | ${_.sample(features)} | 3 | 3 | — | — | — | — |
|
||||
| 5th | +3 | ${_.sample(features)} | 4 | 4 | 2 | — | — | — |
|
||||
| 6th | +3 | ${_.sample(features)} | 4 | 4 | 2 | — | — | — |
|
||||
| 7th | +3 | ${_.sample(features)} | 5 | 4 | 3 | — | — | — |
|
||||
| 8th | +3 | ${_.sample(features)} | 5 | 4 | 3 | — | — | — |
|
||||
| 9th | +4 | ${_.sample(features)} | 6 | 4 | 3 | 2 | — | — |
|
||||
| 10th | +4 | ${_.sample(features)} | 6 | 4 | 3 | 2 | — | — |
|
||||
| 11th | +4 | ${_.sample(features)} | 7 | 4 | 3 | 3 | — | — |
|
||||
| 12th | +4 | ${_.sample(features)} | 7 | 4 | 3 | 3 | — | — |
|
||||
| 13th | +5 | ${_.sample(features)} | 8 | 4 | 3 | 3 | 1 | — |
|
||||
| 14th | +5 | ${_.sample(features)} | 8 | 4 | 3 | 3 | 1 | — |
|
||||
| 15th | +5 | ${_.sample(features)} | 9 | 4 | 3 | 3 | 2 | — |
|
||||
| 16th | +5 | ${_.sample(features)} | 9 | 4 | 3 | 3 | 2 | — |
|
||||
| 17th | +6 | ${_.sample(features)} | 10 | 4 | 3 | 3 | 3 | 1 |
|
||||
| 18th | +6 | ${_.sample(features)} | 10 | 4 | 3 | 3 | 3 | 1 |
|
||||
| 19th | +6 | ${_.sample(features)} | 11 | 4 | 3 | 3 | 3 | 2 |
|
||||
| 20th | +6 | ${_.sample(features)} | 11 | 4 | 3 | 3 | 3 | 2 |
|
||||
}}\n\n`;
|
||||
},
|
||||
|
||||
let cantrips = 3;
|
||||
let spells = 1;
|
||||
let slots = 2;
|
||||
return `{{${classes}\n##### ${classname} Spellcasting\n` +
|
||||
`| Class | Cantrips | Spells |--- Spells Slots per Spell Level ---||||\n` +
|
||||
`| Level ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th |\n` +
|
||||
`|:------:|:--------:|:-------:|:-------:|:-------:|:-------:|:-------:|\n${
|
||||
_.map(levels, function(levelName, level){
|
||||
const res = [
|
||||
_.pad(levelName, 6),
|
||||
_.pad(cantrips.toString(), 8),
|
||||
_.pad(spells.toString(), 7),
|
||||
drawSlots(slots, 4, 7),
|
||||
].join(' | ');
|
||||
|
||||
cantrips += _.random(0, 1);
|
||||
spells += _.random(0, 1);
|
||||
slots += _.random(0, 1);
|
||||
|
||||
return `| ${res} |`;
|
||||
}).join('\n')}\n}}\n\n`;
|
||||
third : function(snippetClasses){
|
||||
return dedent`
|
||||
{{${snippetClasses}
|
||||
##### ${_.sample(classnames)} Spellcasting
|
||||
| Level | Cantrips | Spells |--- Spells Slots per Spell Level ---||||
|
||||
| ^| Known ^| Known ^| 1st | 2nd | 3rd | 4th |
|
||||
|:-----:|:--------:|:------:|:-------:|:-------:|:-------:|:-------:|
|
||||
| 3rd | 2 | 3 | 2 | — | — | — |
|
||||
| 4th | 2 | 4 | 3 | — | — | — |
|
||||
| 5th | 2 | 4 | 3 | — | — | — |
|
||||
| 6th | 2 | 4 | 3 | — | — | — |
|
||||
| 7th | 2 | 5 | 4 | 2 | — | — |
|
||||
| 8th | 2 | 6 | 4 | 2 | — | — |
|
||||
| 9th | 2 | 6 | 4 | 2 | — | — |
|
||||
| 10th | 3 | 7 | 4 | 3 | — | — |
|
||||
| 11th | 3 | 8 | 4 | 3 | — | — |
|
||||
| 12th | 3 | 8 | 4 | 3 | — | — |
|
||||
| 13th | 3 | 9 | 4 | 3 | 2 | — |
|
||||
| 14th | 3 | 10 | 4 | 3 | 2 | — |
|
||||
| 15th | 3 | 10 | 4 | 3 | 2 | — |
|
||||
| 16th | 3 | 11 | 4 | 3 | 3 | — |
|
||||
| 17th | 3 | 11 | 4 | 3 | 3 | — |
|
||||
| 18th | 3 | 11 | 4 | 3 | 3 | — |
|
||||
| 19th | 3 | 12 | 4 | 3 | 3 | 1 |
|
||||
| 20th | 3 | 13 | 4 | 3 | 3 | 1 |
|
||||
}}\n\n`;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -29,21 +29,23 @@ const getTOC = (pages)=>{
|
||||
|
||||
const res = [];
|
||||
_.each(pages, (page, pageNum)=>{
|
||||
const lines = page.split('\n');
|
||||
_.each(lines, (line)=>{
|
||||
if(_.startsWith(line, '# ')){
|
||||
const title = line.replace('# ', '');
|
||||
add1(title, pageNum);
|
||||
}
|
||||
if(_.startsWith(line, '## ')){
|
||||
const title = line.replace('## ', '');
|
||||
add2(title, pageNum);
|
||||
}
|
||||
if(_.startsWith(line, '### ')){
|
||||
const title = line.replace('### ', '');
|
||||
add3(title, pageNum);
|
||||
}
|
||||
});
|
||||
if(!page.includes("{{frontCover}}") && !page.includes("{{insideCover}}") && !page.includes("{{partCover}}") && !page.includes("{{backCover}}")) {
|
||||
const lines = page.split('\n');
|
||||
_.each(lines, (line)=>{
|
||||
if(_.startsWith(line, '# ')){
|
||||
const title = line.replace('# ', '');
|
||||
add1(title, pageNum);
|
||||
}
|
||||
if(_.startsWith(line, '## ')){
|
||||
const title = line.replace('## ', '');
|
||||
add2(title, pageNum);
|
||||
}
|
||||
if(_.startsWith(line, '### ')){
|
||||
const title = line.replace('### ', '');
|
||||
add3(title, pageNum);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return res;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user