From 1288864fb6777292fd5ddd0d3d6e3788e86add59 Mon Sep 17 00:00:00 2001
From: pedroth
Date: Tue, 14 Nov 2023 22:56:24 +0000
Subject: [PATCH] fix bug in html parsing add html comments
---
dist/node/CodeRender/CodeRender.js | 47 +++++++++++++++++++++++-----
dist/node/Lexer.js | 12 ++++++-
dist/node/MathRender.js | 49 ++++++++++++++++++++++++-----
dist/node/NabladownRender.js | 49 ++++++++++++++++++++++++-----
dist/node/Parser.js | 40 +++++++++++++++++++-----
dist/node/Render.js | 49 ++++++++++++++++++++++++-----
dist/node/index.js | 50 +++++++++++++++++++++++++-----
dist/web/CodeRender/CodeRender.js | 47 +++++++++++++++++++++++-----
dist/web/Lexer.js | 12 ++++++-
dist/web/MathRender.js | 47 +++++++++++++++++++++++-----
dist/web/NabladownRender.js | 47 +++++++++++++++++++++++-----
dist/web/Parser.js | 40 +++++++++++++++++++-----
dist/web/Render.js | 47 +++++++++++++++++++++++-----
dist/web/index.js | 48 +++++++++++++++++++++++-----
index.js | 9 +++---
src/Lexer.js | 2 ++
src/Parser.js | 50 +++++++++++++++++++++---------
src/Render.js | 11 +++++++
src/Utils.js | 4 +++
src/buildDom.js | 11 ++++---
test/resources/snapshot2.html | 2 +-
test/resources/test2.nd | 22 +++++++++----
22 files changed, 575 insertions(+), 120 deletions(-)
diff --git a/dist/node/CodeRender/CodeRender.js b/dist/node/CodeRender/CodeRender.js
index c384435..8d6a467 100644
--- a/dist/node/CodeRender/CodeRender.js
+++ b/dist/node/CodeRender/CodeRender.js
@@ -47335,7 +47335,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -47366,6 +47366,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -47389,6 +47390,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -47397,6 +47400,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -47453,6 +47458,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -47725,6 +47733,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -48296,6 +48306,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -48303,9 +48316,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -48317,15 +48330,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -48353,7 +48378,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -48462,7 +48487,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -48516,6 +48541,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -62717,6 +62743,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -62758,6 +62788,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
diff --git a/dist/node/Lexer.js b/dist/node/Lexer.js
index 3ca17a5..99864b3 100644
--- a/dist/node/Lexer.js
+++ b/dist/node/Lexer.js
@@ -122,7 +122,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -153,6 +153,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -176,6 +177,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -184,6 +187,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -240,6 +245,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -512,6 +520,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
diff --git a/dist/node/MathRender.js b/dist/node/MathRender.js
index 2cba328..afbf942 100644
--- a/dist/node/MathRender.js
+++ b/dist/node/MathRender.js
@@ -122,7 +122,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -153,6 +153,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -176,6 +177,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -184,6 +187,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -240,6 +245,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -512,6 +520,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -1083,6 +1093,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -1090,9 +1103,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -1104,15 +1117,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -1140,7 +1165,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -1249,7 +1274,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -1303,6 +1328,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -12661,7 +12687,7 @@ var controlWordWhitespaceRegexString = "(" + controlWordRegexString + ")" + spac
var controlSpaceRegexString = "\\\\(\n|[ \r\t]+\n?)[ \r\t]*";
var combiningDiacriticalMarkString = "[\u0300-\u036F]";
var combiningDiacriticalMarksEndRegex = new RegExp(combiningDiacriticalMarkString + "+$");
-var tokenRegexString = "(" + spaceRegexString + "+)|" + (controlSpaceRegexString + "|") + "([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + (combiningDiacriticalMarkString + "*") + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + (combiningDiacriticalMarkString + "*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5") + ("|" + controlWordWhitespaceRegexString) + ("|" + controlSymbolRegexString + ")");
+var tokenRegexString = "(" + spaceRegexString + "+)|" + (controlSpaceRegexString + "|") + "([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + (combiningDiacriticalMarkString + "*") + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + (combiningDiacriticalMarkString + "*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5") + ("|" + controlWordWhitespaceRegexString) + ("|" + controlSymbolRegexString + ")");
class Lexer2 {
constructor(input, settings) {
@@ -15504,6 +15530,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -15545,6 +15575,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
diff --git a/dist/node/NabladownRender.js b/dist/node/NabladownRender.js
index edb86db..5a48bf4 100644
--- a/dist/node/NabladownRender.js
+++ b/dist/node/NabladownRender.js
@@ -47335,7 +47335,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -47366,6 +47366,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -47389,6 +47390,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -47397,6 +47400,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -47453,6 +47458,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -47725,6 +47733,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -48296,6 +48306,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -48303,9 +48316,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -48317,15 +48330,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -48353,7 +48378,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -48462,7 +48487,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -48516,6 +48541,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -59874,7 +59900,7 @@ var controlWordWhitespaceRegexString = "(" + controlWordRegexString + ")" + spac
var controlSpaceRegexString = "\\\\(\n|[ \r\t]+\n?)[ \r\t]*";
var combiningDiacriticalMarkString = "[\u0300-\u036F]";
var combiningDiacriticalMarksEndRegex = new RegExp(combiningDiacriticalMarkString + "+$");
-var tokenRegexString = "(" + spaceRegexString + "+)|" + (controlSpaceRegexString + "|") + "([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + (combiningDiacriticalMarkString + "*") + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + (combiningDiacriticalMarkString + "*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5") + ("|" + controlWordWhitespaceRegexString) + ("|" + controlSymbolRegexString + ")");
+var tokenRegexString = "(" + spaceRegexString + "+)|" + (controlSpaceRegexString + "|") + "([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + (combiningDiacriticalMarkString + "*") + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + (combiningDiacriticalMarkString + "*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5") + ("|" + controlWordWhitespaceRegexString) + ("|" + controlSymbolRegexString + ")");
class Lexer2 {
constructor(input, settings) {
@@ -62717,6 +62743,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -62758,6 +62788,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
diff --git a/dist/node/Parser.js b/dist/node/Parser.js
index cf5dfbc..e4d8c70 100644
--- a/dist/node/Parser.js
+++ b/dist/node/Parser.js
@@ -122,7 +122,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -153,6 +153,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -176,6 +177,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -184,6 +187,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -240,6 +245,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -512,6 +520,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -1083,6 +1093,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -1090,9 +1103,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -1104,15 +1117,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -1140,7 +1165,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -1249,7 +1274,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -1303,6 +1328,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
diff --git a/dist/node/Render.js b/dist/node/Render.js
index 8dd6cb5..6aa2af1 100644
--- a/dist/node/Render.js
+++ b/dist/node/Render.js
@@ -122,7 +122,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -153,6 +153,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -176,6 +177,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -184,6 +187,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -240,6 +245,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -512,6 +520,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -1083,6 +1093,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -1090,9 +1103,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -1104,15 +1117,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -1140,7 +1165,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -1249,7 +1274,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -1303,6 +1328,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -12661,7 +12687,7 @@ var controlWordWhitespaceRegexString = "(" + controlWordRegexString + ")" + spac
var controlSpaceRegexString = "\\\\(\n|[ \r\t]+\n?)[ \r\t]*";
var combiningDiacriticalMarkString = "[\u0300-\u036F]";
var combiningDiacriticalMarksEndRegex = new RegExp(combiningDiacriticalMarkString + "+$");
-var tokenRegexString = "(" + spaceRegexString + "+)|" + (controlSpaceRegexString + "|") + "([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + (combiningDiacriticalMarkString + "*") + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + (combiningDiacriticalMarkString + "*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5") + ("|" + controlWordWhitespaceRegexString) + ("|" + controlSymbolRegexString + ")");
+var tokenRegexString = "(" + spaceRegexString + "+)|" + (controlSpaceRegexString + "|") + "([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + (combiningDiacriticalMarkString + "*") + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + (combiningDiacriticalMarkString + "*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5") + ("|" + controlWordWhitespaceRegexString) + ("|" + controlSymbolRegexString + ")");
class Lexer2 {
constructor(input, settings) {
@@ -15504,6 +15530,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -15545,6 +15575,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
diff --git a/dist/node/index.js b/dist/node/index.js
index 8689389..693409e 100644
--- a/dist/node/index.js
+++ b/dist/node/index.js
@@ -47335,7 +47335,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -47366,6 +47366,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -47389,6 +47390,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -47397,6 +47400,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -47453,6 +47458,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -47725,6 +47733,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -48296,6 +48306,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -48303,9 +48316,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -48317,15 +48330,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -48353,7 +48378,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -48462,7 +48487,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -48516,6 +48541,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -59874,7 +59900,7 @@ var controlWordWhitespaceRegexString = "(" + controlWordRegexString + ")" + spac
var controlSpaceRegexString = "\\\\(\n|[ \r\t]+\n?)[ \r\t]*";
var combiningDiacriticalMarkString = "[\u0300-\u036F]";
var combiningDiacriticalMarksEndRegex = new RegExp(combiningDiacriticalMarkString + "+$");
-var tokenRegexString = "(" + spaceRegexString + "+)|" + (controlSpaceRegexString + "|") + "([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + (combiningDiacriticalMarkString + "*") + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + (combiningDiacriticalMarkString + "*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5") + ("|" + controlWordWhitespaceRegexString) + ("|" + controlSymbolRegexString + ")");
+var tokenRegexString = "(" + spaceRegexString + "+)|" + (controlSpaceRegexString + "|") + "([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + (combiningDiacriticalMarkString + "*") + "|[\uD800-\uDBFF][\uDC00-\uDFFF]" + (combiningDiacriticalMarkString + "*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5") + ("|" + controlWordWhitespaceRegexString) + ("|" + controlSymbolRegexString + ")");
class Lexer2 {
constructor(input, settings) {
@@ -62717,6 +62743,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -62758,6 +62788,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
@@ -62966,6 +62999,7 @@ export {
evalScriptTag,
either,
eatSymbolsWhile,
+ eatSpacesTabsAndNewLines,
eatSpaces,
eatNSymbol,
createDefaultEl,
diff --git a/dist/web/CodeRender/CodeRender.js b/dist/web/CodeRender/CodeRender.js
index e01ef7b..37b421c 100644
--- a/dist/web/CodeRender/CodeRender.js
+++ b/dist/web/CodeRender/CodeRender.js
@@ -47335,7 +47335,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -47366,6 +47366,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -47389,6 +47390,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -47397,6 +47400,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -47453,6 +47458,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -47725,6 +47733,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -48296,6 +48306,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -48303,9 +48316,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -48317,15 +48330,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -48353,7 +48378,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -48462,7 +48487,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -48516,6 +48541,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -62717,6 +62743,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -62758,6 +62788,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
diff --git a/dist/web/Lexer.js b/dist/web/Lexer.js
index 3aafdf0..2619c70 100644
--- a/dist/web/Lexer.js
+++ b/dist/web/Lexer.js
@@ -122,7 +122,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -153,6 +153,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -176,6 +177,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -184,6 +187,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -240,6 +245,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -512,6 +520,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
diff --git a/dist/web/MathRender.js b/dist/web/MathRender.js
index 6db84ae..ec4f33e 100644
--- a/dist/web/MathRender.js
+++ b/dist/web/MathRender.js
@@ -122,7 +122,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -153,6 +153,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -176,6 +177,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -184,6 +187,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -240,6 +245,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -512,6 +520,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -1083,6 +1093,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -1090,9 +1103,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -1104,15 +1117,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -1140,7 +1165,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -1249,7 +1274,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -1303,6 +1328,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -15504,6 +15530,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -15545,6 +15575,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
diff --git a/dist/web/NabladownRender.js b/dist/web/NabladownRender.js
index a557854..5a2b2b8 100644
--- a/dist/web/NabladownRender.js
+++ b/dist/web/NabladownRender.js
@@ -47335,7 +47335,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -47366,6 +47366,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -47389,6 +47390,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -47397,6 +47400,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -47453,6 +47458,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -47725,6 +47733,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -48296,6 +48306,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -48303,9 +48316,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -48317,15 +48330,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -48353,7 +48378,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -48462,7 +48487,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -48516,6 +48541,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -62717,6 +62743,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -62758,6 +62788,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
diff --git a/dist/web/Parser.js b/dist/web/Parser.js
index 67a4c7f..648d09e 100644
--- a/dist/web/Parser.js
+++ b/dist/web/Parser.js
@@ -122,7 +122,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -153,6 +153,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -176,6 +177,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -184,6 +187,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -240,6 +245,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -512,6 +520,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -1083,6 +1093,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -1090,9 +1103,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -1104,15 +1117,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -1140,7 +1165,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -1249,7 +1274,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -1303,6 +1328,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
diff --git a/dist/web/Render.js b/dist/web/Render.js
index 44c2804..42f5f7c 100644
--- a/dist/web/Render.js
+++ b/dist/web/Render.js
@@ -122,7 +122,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -153,6 +153,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -176,6 +177,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -184,6 +187,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -240,6 +245,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -512,6 +520,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -1083,6 +1093,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -1090,9 +1103,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -1104,15 +1117,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -1140,7 +1165,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -1249,7 +1274,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -1303,6 +1328,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -15504,6 +15530,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -15545,6 +15575,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
diff --git a/dist/web/index.js b/dist/web/index.js
index f0094e7..8755281 100644
--- a/dist/web/index.js
+++ b/dist/web/index.js
@@ -47335,7 +47335,7 @@ function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach((child) => {
- if (!child.build)
+ if (!child.build || child.isEmpty())
return;
dom.appendChild(child.build());
});
@@ -47366,6 +47366,7 @@ function buildDom(nodeType) {
domNode.getLazyActions = () => lazyActions;
domNode.getType = () => nodeType;
domNode.getRef = () => (f) => f(maybe(ref));
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
var childrenToString = function({
@@ -47389,6 +47390,8 @@ var childrenToString = function({
};
var startTagToString = function({ nodeType, attrs, isFormatted }) {
const result = [];
+ if (!nodeType)
+ return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -47397,6 +47400,8 @@ var startTagToString = function({ nodeType, attrs, isFormatted }) {
return result;
};
var endTagToString = function({ nodeType, isFormatted, n }) {
+ if (!nodeType)
+ return "";
const indentation = Array(n).fill(" ").join("");
const result = [];
if (isFormatted)
@@ -47453,6 +47458,9 @@ function eatNSymbol(n, symbolPredicate) {
function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, (s) => s.type === " ");
}
+function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, (s) => s.type === " " || s.type === "\t" || s.type === "\n");
+}
function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
@@ -47725,6 +47733,8 @@ var tokenBuilder = () => {
var TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
@@ -48296,6 +48306,9 @@ var parseHtml = function(stream2) {
}, () => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream2);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ }, () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream2);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
});
};
var parseStartTag = function(stream2) {
@@ -48303,9 +48316,9 @@ var parseStartTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === ">") {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -48317,15 +48330,27 @@ var parseEmptyTag = function(stream2) {
if (token.type === "<") {
const nextStream1 = eatSpaces(stream2.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1);
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (nextStream5.head().type === "/>") {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
}
throw new Error(`Error occurred while parsing EmptyTag,` + stream2.toString());
};
+var parseCommentTag = function(stream2) {
+ return success(stream2).filter((nextStream) => {
+ return nextStream.head().type === "")(nextStream.tail());
+ if (AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream2.toString()}`);
+ });
+};
function parseAlphaNumName(tokenStream) {
const strBuffer = [];
let s = tokenStream;
@@ -48353,7 +48378,7 @@ var parseCharAlphaNumName = function(charStream) {
var parseAttrs = function(stream2) {
return or(() => {
const { left: Attr, right: nextStream } = parseAttr(stream2);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -48462,7 +48487,7 @@ var parseInnerHtmlTypes = function(stream2) {
});
};
var parseEndTag = function(stream2) {
- const filteredStream = eatSymbolsWhile(stream2, (token2) => token2.type === " " || token2.type === "\t" || token2.type === "\n");
+ const filteredStream = eatSpacesTabsAndNewLines(stream2);
const token = filteredStream.head();
if (token.type === "") {
const nextStream1 = eatSpaces(filteredStream.tail());
@@ -48516,6 +48541,7 @@ var TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -62717,6 +62743,10 @@ class Render {
{
predicate: (h) => !!h.EmptyTag,
value: (h) => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: (h) => !!h.CommentTag,
+ value: (h) => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -62758,6 +62788,9 @@ class Render {
attributes.forEach(({ attributeName, attributeValue }) => container.attr(attributeName, attributeValue));
return container;
}
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
renderNablaText(text2) {
const { left: Expression } = parseExpression(tokenizer(stream(text2)));
if (Expression.expressions.length > 0) {
@@ -62966,6 +62999,7 @@ export {
evalScriptTag,
either,
eatSymbolsWhile,
+ eatSpacesTabsAndNewLines,
eatSpaces,
eatNSymbol,
createDefaultEl,
diff --git a/index.js b/index.js
index 77acb8c..ab9de70 100644
--- a/index.js
+++ b/index.js
@@ -156,12 +156,13 @@ function renderEditor(anchor) {
// eslint-disable-next-line no-undef
const editor = monaco.editor.create(anchor, {
value: "",
- language: "markdown",
+ fontSize: "16",
+ theme: "vs-dark",
lineNumbers: "on",
+ insertSpaces: false,
+ language: "markdown",
+ automaticLayout: true,
wordWrap: "wordWrapColumn",
- theme: "vs-dark",
- fontSize: "16",
- automaticLayout: true
});
return editor;
}
diff --git a/src/Lexer.js b/src/Lexer.js
index 0defa15..aaf3105 100644
--- a/src/Lexer.js
+++ b/src/Lexer.js
@@ -179,6 +179,8 @@ function orToken(...tokenParsers) {
const TOKENS_PARSERS = [
tokenRepeat("#", 6),
tokenRepeat("$", 2),
+ tokenSymbol(""),
tokenSymbol("*"),
tokenSymbol("_"),
tokenSymbol(CUSTOM_SYMBOL),
diff --git a/src/Parser.js b/src/Parser.js
index ab061fd..8a521fe 100644
--- a/src/Parser.js
+++ b/src/Parser.js
@@ -22,7 +22,8 @@ import {
eatSpaces,
isNumeric,
eatSymbolsWhile,
- returnOne
+ returnOne,
+ eatSpacesTabsAndNewLines
} from "./Utils.js";
/**
@@ -124,21 +125,21 @@ import {
*
* SingleBut(s) -> ¬s
*
- * Html -> StartTag InnerHtml EndTag / EmptyTag
+ * Html -> StartTag InnerHtml EndTag / EmptyTag / CommentTag
*
* InnerHtml -> InnerHtmlTypes InnerHtml / ε
*
* InnerHtmlTypes -> Html / Paragraph / Expression*
*
- * StartTag -> (" " || "\n")* < (" ")* AlphaNumName (" ")* Attrs (" ")*>
+ * StartTag -> < (" ")* AlphaNumName (" " || "\n")* Attrs (" " || "\n")*>
*
- * EmptyTag -> <(" ")* AlphaNumName (" ")* />
+ * EmptyTag -> <(" ")* AlphaNumName (" " || "\n")* Attrs (" " || "\n")* />
*
- * Attrs -> Attr Attrs / ε
+ * Attrs -> Attr (" " || "\n")* Attrs / ε
*
* Attr -> AlphaNumName="AnyBut(")" / AlphaNumName='AnyBut(')'
*
- * EndTag -> (" " || "\n")* (" ")*AlphaNumName(" ")*>
+ * EndTag -> (" ")*AlphaNumName(" ")*>
*
* AlphaNumName -> [a-zA-z][a-zA-Z0-9]*
*
@@ -185,6 +186,7 @@ export const TYPES = {
html: "html",
startTag: "startTag",
emptyTag: "emptyTag",
+ commentTag: "commentTag",
innerHtml: "innerHtml",
innerHtmlTypes: "innerHtmlTypes",
endTag: "endTag",
@@ -1078,6 +1080,10 @@ function parseHtml(stream) {
() => {
const { left: EmptyTag, right: nextStream } = parseEmptyTag(stream);
return pair({ type: TYPES.html, EmptyTag }, nextStream);
+ },
+ () => {
+ const { left: CommentTag, right: nextStream } = parseCommentTag(stream);
+ return pair({ type: TYPES.html, CommentTag }, nextStream);
}
);
}
@@ -1090,9 +1096,9 @@ function parseStartTag(stream) {
if ("<" === token.type) {
const nextStream1 = eatSpaces(stream.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1)
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if (">" === nextStream5.head().type) {
return pair({ type: TYPES.startTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -1108,9 +1114,9 @@ function parseEmptyTag(stream) {
if ("<" === token.type) {
const nextStream1 = eatSpaces(stream.tail());
const { left: tagName, right: nextStream2 } = parseAlphaNumName(nextStream1)
- const nextStream3 = eatSpaces(nextStream2);
+ const nextStream3 = eatSpacesTabsAndNewLines(nextStream2);
const { left: Attrs, right: nextStream4 } = parseAttrs(nextStream3);
- const nextStream5 = eatSpaces(nextStream4);
+ const nextStream5 = eatSpacesTabsAndNewLines(nextStream4);
if ("/>" === nextStream5.head().type) {
return pair({ type: TYPES.emptyTag, tag: tagName.text, Attrs }, nextStream5.tail());
}
@@ -1118,6 +1124,23 @@ function parseEmptyTag(stream) {
throw new Error(`Error occurred while parsing EmptyTag,` + stream.toString());
}
+function parseCommentTag(stream) {
+ return success(stream)
+ .filter((nextStream) => {
+ return "' === token.type
+ )(nextStream.tail());
+ if(AnyBut.textArray.length > 0)
+ return pair({ type: TYPES.commentTag }, nextStream1.tail());
+ throw new Error(`Dummy error. Real error to be thrown in _orCatch_ function`);
+ }).orCatch(() => {
+ throw new Error(`Error occurred while parsing Attr, ${stream.toString()}`);
+ })
+}
+
/**
* stream => pair(AlphaNumName, stream)
*/
@@ -1151,7 +1174,7 @@ function parseAttrs(stream) {
return or(
() => {
const { left: Attr, right: nextStream } = parseAttr(stream);
- const nextStreamNoSpaces = eatSpaces(nextStream);
+ const nextStreamNoSpaces = eatSpacesTabsAndNewLines(nextStream);
const { left: Attrs, right: nextStream1 } = parseAttrs(nextStreamNoSpaces);
return pair({
type: TYPES.attrs,
@@ -1325,10 +1348,7 @@ function parseInnerHtmlTypes(stream) {
* stream => pair(EndTag, stream)
*/
function parseEndTag(stream) {
- const filteredStream = eatSymbolsWhile(
- stream,
- token => token.type === " " || token.type === "\t" || token.type === "\n"
- );
+ const filteredStream = eatSpacesTabsAndNewLines(stream);
const token = filteredStream.head();
if ("" === token.type) {
const nextStream1 = eatSpaces(filteredStream.tail());
diff --git a/src/Render.js b/src/Render.js
index 276ae3e..635daa0 100644
--- a/src/Render.js
+++ b/src/Render.js
@@ -688,6 +688,10 @@ export class Render {
{
predicate: h => !!h.EmptyTag,
value: h => this.renderEmptyTag(h.EmptyTag)
+ },
+ {
+ predicate: h => !!h.CommentTag,
+ value: h => this.renderCommentTag(h.CommentTag)
}
])(html);
}
@@ -747,6 +751,13 @@ export class Render {
return container;
}
+ /**
+ * commentTag => DomBuilder
+ */
+ renderCommentTag(commentTag) {
+ return buildDom();
+ }
+
renderNablaText(text) {
const { left: Expression } = parseExpression(tokenizer(stream(text)));
if (Expression.expressions.length > 0) {
diff --git a/src/Utils.js b/src/Utils.js
index 47c025d..80c7d88 100644
--- a/src/Utils.js
+++ b/src/Utils.js
@@ -57,6 +57,10 @@ export function eatSpaces(tokenStream) {
return eatSymbolsWhile(tokenStream, s => s.type === " ");
}
+export function eatSpacesTabsAndNewLines(tokenStream) {
+ return eatSymbolsWhile(tokenStream, s => s.type === " " || s.type === "\t" || s.type === "\n");
+}
+
export function eatSymbolsWhile(tokenStream, predicate) {
let s = tokenStream;
while (!tokenStream.isEmpty()) {
diff --git a/src/buildDom.js b/src/buildDom.js
index 7d448b3..ef2390d 100644
--- a/src/buildDom.js
+++ b/src/buildDom.js
@@ -71,7 +71,7 @@ export function buildDom(nodeType) {
dom.innerHTML = innerHtml;
if (children.length > 0) {
children.forEach(child => {
- if (!child.build) return;
+ if (!child.build || child.isEmpty()) return;
dom.appendChild(child.build())
});
}
@@ -106,6 +106,7 @@ export function buildDom(nodeType) {
domNode.getRef = () => f => f(
maybe(ref)
);
+ domNode.isEmpty = () => !nodeType;
return domNode;
}
@@ -127,9 +128,9 @@ function childrenToString({
const result = [];
const indentation = Array(n + 1).fill(" ").join("")
if (children.length > 0) {
- result.push(...children.map(child =>
- `${isFormatted ? indentation : ""}${child.toString({ isFormatted, n: n + 1 })}${isFormatted ? "\n" : ""}`)
- );
+ result.push(...children.map(child =>
+ `${isFormatted ? indentation : ""}${child.toString({ isFormatted, n: n + 1 })}${isFormatted ? "\n" : ""}`
+ ));
} else {
if (isFormatted) result.push(indentation);
result.push(innerHtml);
@@ -140,6 +141,7 @@ function childrenToString({
function startTagToString({ nodeType, attrs, isFormatted }) {
const result = [];
+ if(!nodeType) return "";
result.push(`<${nodeType}`);
result.push(...Object.entries(attrs).map(([attr, value]) => ` ${attr}="${value}" `));
result.push(`>`);
@@ -148,6 +150,7 @@ function startTagToString({ nodeType, attrs, isFormatted }) {
}
function endTagToString({ nodeType, isFormatted, n }) {
+ if(!nodeType) return "";
const indentation = Array(n).fill(" ").join("")
const result = [];
if (isFormatted) result.push(indentation);
diff --git a/test/resources/snapshot2.html b/test/resources/snapshot2.html
index a3f446a..5e01c6a 100644
--- a/test/resources/snapshot2.html
+++ b/test/resources/snapshot2.html
@@ -68,7 +68,7 @@
System.out.println("Hello")
}
}
-
Syntax here.
Name of the available languages according to highlight.js
HTML
Normal markdown with red text inline
A paragraph with html and nabladown inside:
Custom