mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-24 18:32:41 +00:00
Fix Tables with uneven columns
This commit is contained in:
@@ -1,40 +1,112 @@
|
||||
const _ = require('lodash');
|
||||
const Markdown = require('marked');
|
||||
const renderer = new Markdown.Renderer();
|
||||
const lexer = new Markdown.Lexer();
|
||||
|
||||
//Processes the markdown within an HTML block if it's just a class-wrapper
|
||||
renderer.html = function (html) {
|
||||
if(_.startsWith(_.trim(html), '<div')){
|
||||
let openTag = html.substring(0, html.indexOf('>')+1);
|
||||
let closeTag = '';
|
||||
html = html.substring(html.indexOf('>')+1);
|
||||
if(_.endsWith(_.trim(html), '</div>')){
|
||||
closeTag = '</div>';
|
||||
html = html.substring(0,html.lastIndexOf('</div'));
|
||||
// Copied directly from Marked helpers.js source with permission
|
||||
function splitCells(tableRow, count) {
|
||||
// ensure that every cell-delimiting pipe has a space
|
||||
// before it to distinguish it from an escaped pipe
|
||||
const row = tableRow.replace(/\|/g, (match, offset, str) => {
|
||||
let escaped = false,
|
||||
curr = offset;
|
||||
while (--curr >= 0 && str[curr] === '\\') escaped = !escaped;
|
||||
if (escaped) {
|
||||
// odd number of slashes means | is escaped
|
||||
// so we leave it alone
|
||||
return '|';
|
||||
} else {
|
||||
// add space before unescaped |
|
||||
return ' |';
|
||||
}
|
||||
}),
|
||||
cells = row.split(/ \|/);
|
||||
let i = 0;
|
||||
|
||||
if (cells.length > count) {
|
||||
cells.splice(count);
|
||||
} else {
|
||||
while (cells.length < count) cells.push('');
|
||||
}
|
||||
|
||||
for (; i < cells.length; i++) {
|
||||
// leading or trailing whitespace is ignored per the gfm spec
|
||||
cells[i] = cells[i].trim().replace(/\\\|/g, '|');
|
||||
}
|
||||
return cells;
|
||||
}
|
||||
|
||||
const renderer = {
|
||||
// Adjust the way html is handled
|
||||
html(html) {
|
||||
// Processes the markdown within an HTML block if it's just a class-wrapper
|
||||
if(_.startsWith(_.trim(html), '<div')){
|
||||
let openTag = html.substring(0, html.indexOf('>')+1);
|
||||
let closeTag = '';
|
||||
html = html.substring(html.indexOf('>')+1);
|
||||
if(_.endsWith(_.trim(html), '</div>')){
|
||||
closeTag = '</div>';
|
||||
html = html.substring(0,html.lastIndexOf('</div'));
|
||||
}
|
||||
return `${openTag} ${Markdown(html)} ${closeTag}`;
|
||||
}
|
||||
return `${openTag} ${Markdown(html)} ${closeTag}`;
|
||||
}
|
||||
|
||||
// Allow raw HTML tags to end without a blank line if markdown is right after
|
||||
if(html.includes('\n')){
|
||||
let openTag = html.substring(0, html.indexOf('>')+1);
|
||||
if(!_.endsWith(_.trim(html), '>')){ // If there is no closing tag, parse markdown directly after
|
||||
let remainder = html.substring(html.indexOf('>')+1);
|
||||
return `${openTag} ${Markdown(remainder)}`;
|
||||
// Allow raw HTML tags to end without a blank line if markdown is right after
|
||||
if(html.includes('\n')){
|
||||
let openTag = html.substring(0, html.indexOf('>')+1);
|
||||
if(!_.endsWith(_.trim(html), '>')){ // If there is no closing tag, parse markdown directly after
|
||||
let remainder = html.substring(html.indexOf('>')+1);
|
||||
return `${openTag} ${Markdown(remainder)}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Above may work better if we just force <script, <pre and <style
|
||||
// tags to return directly instead of working around <divs>
|
||||
/*if(_.startsWith(_.trim(html), '<script')){
|
||||
return html;
|
||||
}*/
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
// Above may work better if we just explicitly allow <script, <pre and <style
|
||||
// tags to return directly
|
||||
/*if(_.startsWith(_.trim(html), '<script')){
|
||||
return html;
|
||||
}*/
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
console.log(lexer.rules);
|
||||
const tokenizer = {
|
||||
//Adjust tables to work even if columns are uneven
|
||||
table(src) {
|
||||
const cap = this.rules.block.table.exec(src);
|
||||
if (cap) {
|
||||
const item = {
|
||||
type: 'table',
|
||||
header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
|
||||
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
|
||||
cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : []
|
||||
};
|
||||
|
||||
item.raw = cap[0];
|
||||
|
||||
let l = item.align.length;
|
||||
let i;
|
||||
for (i = 0; i < l; i++) {
|
||||
if (/^ *-+: *$/.test(item.align[i])) {
|
||||
item.align[i] = 'right';
|
||||
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
||||
item.align[i] = 'center';
|
||||
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
||||
item.align[i] = 'left';
|
||||
} else {
|
||||
item.align[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
l = item.cells.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
item.cells[i] = splitCells(
|
||||
item.cells[i].replace(/^ *\| *| *\| *$/g, ''),
|
||||
item.header.length);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*renderer.code = function (code, infostring, escaped) {
|
||||
if(code == ''){
|
||||
@@ -43,6 +115,8 @@ console.log(lexer.rules);
|
||||
return code;
|
||||
}*/
|
||||
|
||||
Markdown.use({ renderer, tokenizer });
|
||||
|
||||
const sanatizeScriptTags = (content)=>{
|
||||
return content
|
||||
.replace(/<script/ig, '<script')
|
||||
@@ -60,10 +134,7 @@ module.exports = {
|
||||
marked : Markdown,
|
||||
render : (rawBrewText)=>{
|
||||
return Markdown(
|
||||
sanatizeScriptTags(rawBrewText),
|
||||
{ renderer: renderer,
|
||||
lexer: lexer }
|
||||
);
|
||||
sanatizeScriptTags(rawBrewText));
|
||||
},
|
||||
|
||||
validate : (rawBrewText)=>{
|
||||
|
||||
Reference in New Issue
Block a user