Javascript Markdown 解析
Javascript Markdown Parsing
我正在研究 html 解析器的降价。我知道这是一个大项目并且有第三方库,但是 none 我越不想自己推出一个不需要处理降价的每个方面的简单解决方案。
到目前为止,过程是获取输入(在我的例子中是文本区域的值)并逐行解析它。
var html = [];
var lines = txt.split('\n'); //Convert string to array
//Remove empty lines
for(var index = lines.length-1; index >= 0; index--) {
if(lines[index] == '') lines.splice(index, 1);
}
//Parse line by line
for(var index = 0; index <= lines.length-1; index++) {
var str = lines[index];
if(str.match(/^#[^#]/)) {
//Header
str = str.replace(/#(.*?)$/g, '<h1></h1>');
} else if(str.match(/^##[^#]/)) {
//Header 2
str = str.replace(/##(.*?)$/g, '<h2></h2>');
} else if(str.match(/^###[^#]/)) {
//Header 3
str = str.replace(/###(.*?)$/g, '<h3></h3>');
} else if(str.trim().startsWith('+')) {
//Unordered List
var orig = str;
str = str.replace(/\+(.*?)$/, '<li></li>');
var previous, next;
if(index > 0) previous = lines[index-1];
if(!previous || previous && previous.indexOf('+') < orig.indexOf('+')) {
str = '<ul>' + str;
}
if(index < lines.length-1) next = lines[index+1];
if(!next || next && next.indexOf('+') < orig.indexOf('+')) {
var count = Math.max(0, orig.indexOf('+') / 4);
if(next) count = count - Math.max(0, next.indexOf('+') / 4);
for(var i=1; i<=count; i++) {
str = str + '</ul>';
}
}
if(next && next.trim().indexOf('+') == -1) str = str + '</ul>';
} else if(str.match(/^[0-9a-zA-Z]/)) {
//Paragraph
str = str.replace(/^([0-9a-zA-Z].*?)$/g, '<p></p>');
}
//Inline formatting
str = str.replace(/\*\*(.*?)\*\*/g, '<strong></strong>'); //Bold
str = str.replace(/\_\_(.*?)\_\_/g, '<strong></strong>'); //Another bold
str = str.replace(/\*(.*?)\*/g, '<em></em>'); //Italics
str = str.replace(/\_(.*?)\_/g, '<em></em>'); //Another italics
//Append formatted to return string
html.push(str);
}
我 运行 遇到问题的地方是嵌套块,例如 ul。目前代码查看以 + 开头的行并将其包装在 li 中。很好,但是这些列表项永远不会放在 ul 中。我可以 运行 在逐行之后再次通过输出,然后将每组 li 包装起来,但是当我嵌套了需要自己的 ul 的 li 时,这把我搞砸了。
对如何应用这些额外的包装标签有什么想法吗?我考虑过在列表类型元素周围使用我自己的特殊字符,以便我知道在哪里添加包装标签,但这打破了传统的降价。我无法将原始降价信息传递给除我以外的其他人,并且知道他们会理解发生了什么。
编辑 我更新了我的代码示例以包含一个工作示例。工作示例还支持嵌套列表。
你需要一个非常简单的状态机。
当您遇到第一个 +
时,您添加 <ul>
并举起旗帜。
如果您没有看到以 +
开头的行并且您的旗帜已升起,请关闭 </ul>
我正在研究 html 解析器的降价。我知道这是一个大项目并且有第三方库,但是 none 我越不想自己推出一个不需要处理降价的每个方面的简单解决方案。
到目前为止,过程是获取输入(在我的例子中是文本区域的值)并逐行解析它。
var html = [];
var lines = txt.split('\n'); //Convert string to array
//Remove empty lines
for(var index = lines.length-1; index >= 0; index--) {
if(lines[index] == '') lines.splice(index, 1);
}
//Parse line by line
for(var index = 0; index <= lines.length-1; index++) {
var str = lines[index];
if(str.match(/^#[^#]/)) {
//Header
str = str.replace(/#(.*?)$/g, '<h1></h1>');
} else if(str.match(/^##[^#]/)) {
//Header 2
str = str.replace(/##(.*?)$/g, '<h2></h2>');
} else if(str.match(/^###[^#]/)) {
//Header 3
str = str.replace(/###(.*?)$/g, '<h3></h3>');
} else if(str.trim().startsWith('+')) {
//Unordered List
var orig = str;
str = str.replace(/\+(.*?)$/, '<li></li>');
var previous, next;
if(index > 0) previous = lines[index-1];
if(!previous || previous && previous.indexOf('+') < orig.indexOf('+')) {
str = '<ul>' + str;
}
if(index < lines.length-1) next = lines[index+1];
if(!next || next && next.indexOf('+') < orig.indexOf('+')) {
var count = Math.max(0, orig.indexOf('+') / 4);
if(next) count = count - Math.max(0, next.indexOf('+') / 4);
for(var i=1; i<=count; i++) {
str = str + '</ul>';
}
}
if(next && next.trim().indexOf('+') == -1) str = str + '</ul>';
} else if(str.match(/^[0-9a-zA-Z]/)) {
//Paragraph
str = str.replace(/^([0-9a-zA-Z].*?)$/g, '<p></p>');
}
//Inline formatting
str = str.replace(/\*\*(.*?)\*\*/g, '<strong></strong>'); //Bold
str = str.replace(/\_\_(.*?)\_\_/g, '<strong></strong>'); //Another bold
str = str.replace(/\*(.*?)\*/g, '<em></em>'); //Italics
str = str.replace(/\_(.*?)\_/g, '<em></em>'); //Another italics
//Append formatted to return string
html.push(str);
}
我 运行 遇到问题的地方是嵌套块,例如 ul。目前代码查看以 + 开头的行并将其包装在 li 中。很好,但是这些列表项永远不会放在 ul 中。我可以 运行 在逐行之后再次通过输出,然后将每组 li 包装起来,但是当我嵌套了需要自己的 ul 的 li 时,这把我搞砸了。
对如何应用这些额外的包装标签有什么想法吗?我考虑过在列表类型元素周围使用我自己的特殊字符,以便我知道在哪里添加包装标签,但这打破了传统的降价。我无法将原始降价信息传递给除我以外的其他人,并且知道他们会理解发生了什么。
编辑 我更新了我的代码示例以包含一个工作示例。工作示例还支持嵌套列表。
你需要一个非常简单的状态机。
当您遇到第一个 +
时,您添加 <ul>
并举起旗帜。
如果您没有看到以 +
开头的行并且您的旗帜已升起,请关闭 </ul>