The BLABBLAB thing is just a replacement of console.log. That way I could saftly grep unwanted console.log next time.
diff --git a/blog/modular/bbcode/parser.js b/blog/modular/bbcode/parser.js
index a2a8282..3fde43b 100644
--- a/blog/modular/bbcode/parser.js
+++ b/blog/modular/bbcode/parser.js
@@ -18,6 +18,12 @@ const decodeStr = function( str )
;
};
+const IsToken = function( c )
+{
+ var v = c.charCodeAt( 0 );
+ return ( 97 <= v && v <= 122 ) || ( 48 <= v && v <= 57 );
+};
+
class BBCodeParser
{
constructor( scopeObj )
@@ -29,11 +35,6 @@ class BBCodeParser
})();
};
- static get stackMatch()
- {
- return /\[(*?)([\s\S]*?)\]([\s\S]*?)\[\/\1\]/ig;
- }
-
static get typeMatch()
{
return /(*)\=\"([^"]+)\"/ig;
@@ -41,7 +42,163 @@ class BBCodeParser
static bbcode_match( str, handler )
{
- return str && str.replace( BBCodeParser.stackMatch, handler );
+ // This function serve as the following RegEx:
+ // = /\[(*?)([\s\S]*?)\]([\s\S]*?)\[\/\1\]/ig;
+ // and because this regex is slow
+ // will now use iteration instead
+
+ var l = str && str.length;
+ var strOut = "";
+
+ var tokenOpened = "";
+ var tokenRCounter = 0;
+
+ var tContent = "";
+ var tOptions = "";
+ var cTTemp;
+
+ for( var i = 0; i < l; i ++ )
+ {
+ var c = str;
+
+ if( c == "[" )
+ {
+ var TokenClosing = "";
+ var mOptions = "";
+ var mToken = "";
+
+ cTTemp = str[ ++ i ];
+
+ if( cTTemp == "/" )
+ {
+ TokenClosing = cTTemp;
+ i ++;
+ }
+
+ // Get Token Name
+ for( cTTemp = str; i < l; i ++, cTTemp = str )
+ {
+ if( IsToken( cTTemp ) )
+ {
+ mToken += cTTemp;
+ continue;
+ }
+
+ break;
+ }
+
+ // No token opened but we got a closing token??!
+ if( !tokenOpened && TokenClosing )
+ {
+ throw new Error( "Syntax Error, Unexpected closing [/" + mToken + "]" );
+ }
+
+ // skip this if we didn't get a token
+ if( !mToken )
+ {
+ // BLABBLAB( "-------> " + cTTemp );
+ if( tokenOpened ) tContent += "[" + cTTemp;
+ else strOut += "[" + cTTemp;
+
+ continue;
+ }
+
+ // BLABBLAB( "Got Token: " + mToken );
+
+ // If said token is not the opened token
+ if( tokenOpened )
+ {
+ var tSkip = ( tokenOpened != mToken );
+
+ if( !tSkip )
+ {
+ if( TokenClosing && 0 < tokenRCounter )
+ {
+ tokenRCounter --;
+ tSkip = true;
+ }
+ // Nested token by the same name
+ // i.e. tokenOpened == mToken
+ else if( !TokenClosing )
+ {
+ tokenRCounter ++;
+ tSkip = true;
+ }
+ }
+
+ if( tSkip )
+ {
+ tContent += "[" + TokenClosing + mToken + "]";
+ continue;
+ }
+ }
+
+ // BLABBLAB( "After Token Name: \"" + cTTemp + "\"" );
+
+ // Closing token does not allow options to be set
+ if( TokenClosing && cTTemp == "]" && mToken == tokenOpened )
+ {
+ // BLABBLAB( "TokenClosed[" + mToken + "]" );
+ // BLABBLAB( "{{{" );
+ // BLABBLAB( tOptions );
+ // BLABBLAB( tContent );
+ // BLABBLAB( "}}}" );
+
+ strOut += handler( mToken, tOptions, tContent );
+
+ mToken
+ = tokenOpened
+ = tOptions
+ = tContent
+ = "";
+ continue;
+ }
+
+ // consume the token options
+ for( cTTemp = str; i < l; i ++, cTTemp = str )
+ {
+ // Unexpected open bracket, invalidate this matching
+ if( cTTemp == "[" )
+ {
+ // BLABBLAB( "\"" + mToken + "\" is in fact not a token" );
+
+ strOut += "[" + mToken;
+
+ // Step back and rematch from here
+ i --;
+
+ mToken
+ = tOptions
+ = tContent
+ = "";
+
+ break;
+ }
+ else if( cTTemp == "]" )
+ {
+ tokenOpened = true;
+ // BLABBLAB( "Token[" + mToken + "] Option: " + tOptions );
+ break;
+ }
+
+ tOptions += cTTemp;
+ }
+
+ tokenOpened = mToken;
+ }
+ else if( tokenOpened )
+ {
+ tContent += c;
+ }
+ else strOut += c;
+ }
+
+ if( tokenOpened )
+ {
+ throw new Error( "Syntax Error, Missing: [/" + tokenOpened + "]" );
+ }
+
+ return strOut;
}
static ParseProps( prop )
@@ -90,7 +247,7 @@ class BBCodeParser
var tokens = {};
// Tokenizer
- var __parse = function( matches, type, props, content )
+ var __parse = function( type, props, content )
{
var name = type.toLowerCase();
@@ -139,5 +296,4 @@ class BBCodeParser
}
}
-
module.exports = BBCodeParser;