mirror of
https://github.com/tenrok/BBob.git
synced 2026-06-05 16:42:27 +03:00
* chore: initial tests * feat: parser test * feat: add case free tags support * fix: coverage upload * fix: --disable=gcov * fix: npm publish sha commit * fix: change codecov to coveralls * fix: change workflow pr build and publish * chore: change coverage badge [skip ci]
This commit is contained in:
@@ -81,11 +81,11 @@ const getTagName = (token: Token) => {
|
||||
return isTagEnd(token) ? value.slice(1) : value;
|
||||
};
|
||||
|
||||
const tokenToText = (token: Token) => {
|
||||
let text = OPEN_BRAKET;
|
||||
const tokenToText = (token: Token, openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET) => {
|
||||
let text = openTag;
|
||||
|
||||
text += getTokenValue(token);
|
||||
text += CLOSE_BRAKET;
|
||||
text += closeTag;
|
||||
|
||||
return text;
|
||||
};
|
||||
@@ -167,8 +167,8 @@ class Token<TokenValue = string> implements TokenInterface {
|
||||
return getEndPosition(this);
|
||||
}
|
||||
|
||||
toString() {
|
||||
return tokenToText(this);
|
||||
toString({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
|
||||
return tokenToText(this, openTag, closeTag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,13 +51,14 @@ export function createLexer(buffer: string, options: LexerOptions = {}): LexerTo
|
||||
let stateMode = STATE_WORD;
|
||||
let tagMode = TAG_STATE_NAME;
|
||||
let contextFreeTag = '';
|
||||
const tokens = new Array<Token<string>>(Math.floor(buffer.length));
|
||||
const tokens = new Array<Token>(Math.floor(buffer.length));
|
||||
const openTag = options.openTag || OPEN_BRAKET;
|
||||
const closeTag = options.closeTag || CLOSE_BRAKET;
|
||||
const escapeTags = !!options.enableEscapeTags;
|
||||
const contextFreeTags = (options.contextFreeTags || [])
|
||||
.filter(Boolean)
|
||||
.map((tag) => tag.toLowerCase());
|
||||
const caseFreeTags = options.caseFreeTags || false;
|
||||
const nestedMap = new Map<string, boolean>();
|
||||
const onToken = options.onToken || (() => {
|
||||
});
|
||||
@@ -88,8 +89,6 @@ export function createLexer(buffer: string, options: LexerOptions = {}): LexerTo
|
||||
|
||||
/**
|
||||
* Emits newly created token to subscriber
|
||||
* @param {Number} type
|
||||
* @param {String} value
|
||||
*/
|
||||
function emitToken(type: number, value: string, startPos?: number, endPos?: number) {
|
||||
const token = createTokenOfType(type, value, row, prevCol, startPos, endPos);
|
||||
@@ -352,13 +351,13 @@ export function createLexer(buffer: string, options: LexerOptions = {}): LexerTo
|
||||
return tokens;
|
||||
}
|
||||
|
||||
function isTokenNested(token: Token) {
|
||||
const value = openTag + SLASH + token.getValue();
|
||||
function isTokenNested(tokenValue: string) {
|
||||
const value = openTag + SLASH + tokenValue;
|
||||
|
||||
if (nestedMap.has(value)) {
|
||||
return !!nestedMap.get(value);
|
||||
} else {
|
||||
const status = (buffer.indexOf(value) > -1);
|
||||
const status = caseFreeTags ? (buffer.toLowerCase().indexOf(value.toLowerCase()) > -1) : (buffer.indexOf(value) > -1);
|
||||
|
||||
nestedMap.set(value, status);
|
||||
|
||||
|
||||
@@ -52,8 +52,9 @@ function parse(input: string, opts: ParseOptions = {}) {
|
||||
const onlyAllowTags = (options.onlyAllowTags || [])
|
||||
.filter(Boolean)
|
||||
.map((tag) => tag.toLowerCase());
|
||||
const caseFreeTags = options.caseFreeTags || false;
|
||||
|
||||
let tokenizer: LexerTokenizer | null = null;
|
||||
let tokenizer: ReturnType<typeof createLexer> | null = null;
|
||||
|
||||
/**
|
||||
* Result AST of nodes
|
||||
@@ -85,10 +86,11 @@ function parse(input: string, opts: ParseOptions = {}) {
|
||||
const nestedTagsMap = new Set<string>();
|
||||
|
||||
function isTokenNested(token: Token) {
|
||||
const value = token.getValue();
|
||||
const tokenValue = token.getValue();
|
||||
const value = caseFreeTags ? tokenValue.toLowerCase() : tokenValue;
|
||||
const { isTokenNested } = tokenizer || {};
|
||||
|
||||
if (!nestedTagsMap.has(value) && isTokenNested && isTokenNested(token)) {
|
||||
if (!nestedTagsMap.has(value) && isTokenNested && isTokenNested(value)) {
|
||||
nestedTagsMap.add(value);
|
||||
|
||||
return true;
|
||||
@@ -101,7 +103,7 @@ function parse(input: string, opts: ParseOptions = {}) {
|
||||
* @private
|
||||
*/
|
||||
function isTagNested(tagName: string) {
|
||||
return Boolean(nestedTagsMap.has(tagName));
|
||||
return Boolean(nestedTagsMap.has(caseFreeTags ? tagName.toLowerCase() : tagName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,17 +205,23 @@ function parse(input: string, opts: ParseOptions = {}) {
|
||||
* @param {Token} token
|
||||
*/
|
||||
function handleTagEnd(token: Token) {
|
||||
const lastTagNode = nestedNodes.last();
|
||||
if (isTagNode(lastTagNode)) {
|
||||
lastTagNode.setEnd({ from: token.getStart(), to: token.getEnd() });
|
||||
}
|
||||
flushTagNodes();
|
||||
|
||||
const tagName = token.getValue().slice(1);
|
||||
const lastNestedNode = nestedNodes.flush();
|
||||
|
||||
flushTagNodes();
|
||||
|
||||
if (lastNestedNode) {
|
||||
const nodes = getNodes();
|
||||
|
||||
if (isTagNode(lastNestedNode)) {
|
||||
lastNestedNode.setEnd({ from: token.getStart(), to: token.getEnd() });
|
||||
}
|
||||
|
||||
appendNodes(nodes, lastNestedNode);
|
||||
} else if (!isTagNested(tagName)) { // when we have only close tag [/some] without any open tag
|
||||
const nodes = getNodes();
|
||||
|
||||
appendNodes(nodes, token.toString({ openTag, closeTag }));
|
||||
} else if (typeof options.onError === "function") {
|
||||
const tag = token.getValue();
|
||||
const line = token.getLine();
|
||||
@@ -281,13 +289,13 @@ function parse(input: string, opts: ParseOptions = {}) {
|
||||
}
|
||||
} else if (token.isTag()) {
|
||||
// if tag is not allowed, just pass it as is
|
||||
appendNodes(nodes, token.toString());
|
||||
appendNodes(nodes, token.toString({ openTag, closeTag }));
|
||||
}
|
||||
} else if (token.isText()) {
|
||||
appendNodes(nodes, tokenValue);
|
||||
} else if (token.isTag()) {
|
||||
// if tag is not allowed, just pass it as is
|
||||
appendNodes(nodes, token.toString());
|
||||
appendNodes(nodes, token.toString({ openTag, closeTag }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,6 +319,7 @@ function parse(input: string, opts: ParseOptions = {}) {
|
||||
closeTag,
|
||||
onlyAllowTags: options.onlyAllowTags,
|
||||
contextFreeTags: options.contextFreeTags,
|
||||
caseFreeTags: options.caseFreeTags,
|
||||
enableEscapeTags: options.enableEscapeTags,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user