UNPKG

@panzer1119/bbcode-parser

Version:
164 lines 6.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Tokenizer = exports.asTextToken = exports.tagToken = exports.textToken = exports.Token = exports.TokenType = void 0; var TokenType; (function (TokenType) { TokenType[TokenType["Text"] = 0] = "Text"; TokenType[TokenType["StartTag"] = 1] = "StartTag"; TokenType[TokenType["EndTag"] = 2] = "EndTag"; })(TokenType = exports.TokenType || (exports.TokenType = {})); //Represents a token var Token = /** @class */ (function () { function Token(tokenType, content, tagAttributes, tagStr) { this.tokenType = tokenType; this.content = content; this.tagAttributes = tagAttributes; this.tagStr = tagStr; } //String representation of the token Token.prototype.toString = function () { return this.content + " (" + TokenType[this.tokenType] + ")"; }; //Check for equality Token.prototype.equals = function (token) { return this.tokenType == token.tokenType && this.content == token.content; }; return Token; }()); exports.Token = Token; //Creates a new text token function textToken(content) { return new Token(TokenType.Text, content); } exports.textToken = textToken; var attributeNameChars = "[a-zA-Z0-9\\.\\-_:;/]"; var attributeValueChars = "[a-zA-Z0-9\\.\\-_:;#/\\s]"; var tokenPattern = "\\[(\\/\\w*)\\]|\\[(\\w*)+(?:=(" + attributeValueChars + "*))?(?: (" + attributeNameChars + "+)=(" + attributeValueChars + "+))*\\]|\\[\\*\\] ?(['\\.,\\-:;#/\\w\\s]+)"; //Creates a new tag token function tagToken(match) { var _a; if (match[1] == undefined) { //Start tag var tagName = match[2]; var attributes = {}; var attributePattern = new RegExp("(" + attributeNameChars + "+)?=(" + attributeValueChars + "+)", "g"); var attributeStr = match[0].substr(1 + tagName.length, match[0].length - 2 - tagName.length); var attributeMatch = void 0; while ((attributeMatch = attributePattern.exec(attributeStr))) { var value = (_a = attributeMatch[2]) === null || _a === void 0 ? void 0 : _a.trim(); if (attributeMatch[1] == undefined) { //The tag attribute attributes[tagName] = value; } else { //Normal attribute attributes[attributeMatch[1]] = value; } } return new Token(TokenType.StartTag, tagName, attributes, match[0]); } else { //End tag return new Token(TokenType.EndTag, match[1].substr(1, match[1].length - 1)); } } exports.tagToken = tagToken; //Converts the given token to a text token function asTextToken(token) { var _a; if (token.tokenType == TokenType.StartTag) { token.content = (_a = token.tagStr) !== null && _a !== void 0 ? _a : ""; token.tokenType = TokenType.Text; //delete token.attributes; //delete token.tagStr; } if (token.tokenType == TokenType.EndTag) { token.content = "[/" + token.content + "]"; token.tokenType = TokenType.Text; } } exports.asTextToken = asTextToken; //Represents a tokenizer var Tokenizer = /** @class */ (function () { //Creates a new tokenizer with the given tags function Tokenizer(bbTags) { this.bbTags = bbTags; } //Tokenizes the given string Tokenizer.prototype.tokenizeString = function (str) { var tokens = this.getTokens(str); var newTokens = []; var noNesting = false; var noNestingTag = ""; var noNestedTagContent = ""; for (var i in tokens) { var currentToken = tokens[i]; var bbTag = this.bbTags[currentToken.content]; var addTag = true; //Replace invalid tags with text if (bbTag === undefined && !noNesting) { asTextToken(currentToken); } else { //Check if current tag doesn't support nesting if (noNesting) { if (currentToken.tokenType == TokenType.EndTag && currentToken.content == noNestingTag) { noNesting = false; newTokens.push(textToken(noNestedTagContent)); } else { asTextToken(currentToken); noNestedTagContent += currentToken.content; addTag = false; } } else { if (bbTag.noNesting && currentToken.tokenType == TokenType.StartTag) { noNesting = true; noNestingTag = currentToken.content; noNestedTagContent = ""; } } } if (addTag) { newTokens.push(currentToken); } } return newTokens; }; //Gets the tokens from the given string Tokenizer.prototype.getTokens = function (str) { var tagPattern = new RegExp(tokenPattern, "g"); var tokens = []; var match; var lastIndex = 0; while ((match = tagPattern.exec(str))) { var deltaInner = match.index - lastIndex; if (deltaInner > 0) { tokens.push(textToken(str.substr(lastIndex, deltaInner))); } if (match[6]) { //Is [*] List Item var tokenStart = new Token(TokenType.StartTag, "*", {}, "[*]"); var tokenText = textToken(match[6]); var tokenEnd = new Token(TokenType.EndTag, "*"); tokens.push(tokenStart); tokens.push(tokenText); tokens.push(tokenEnd); } else { var token = tagToken(match); tokens.push(token); } lastIndex = tagPattern.lastIndex; } var delta = str.length - lastIndex; if (delta > 0) { tokens.push(textToken(str.substr(lastIndex, delta))); } return tokens; }; return Tokenizer; }()); exports.Tokenizer = Tokenizer; //# sourceMappingURL=tokenizer.js.map