bbs-reader.js
function bbsReader(data) {
    var i = 0, match, result = "";
        
    var author, title, time, label, board;
    
    if ((match = /^(\xa7@\xaa\xcc:.*)\n(.*)\n(.*)\n/.exec(data))) {
        // draw header    
        author = stripColon(match[1]);
        title = stripColon(match[2]);
        time = stripColon(match[3]);
        
        // find board
        var t = splitLabel(author);
        author = t[0];
        label = t[1];
        board = t[2];
        
        // 作者
        result += makeHead("\xa7@\xaa\xcc", author, label, board);
        // 標題
        result += makeHead("\xbc\xd0\xc3D", title);
        // 時間
        result += makeHead("\xae\xc9\xb6\xa1", time);
        
        // ─
        result += "<div class='line'><span class='f6'>" + "\xa2w".repeat(39) + "</span></div>";
        
        i += match[0].length;
    }
    
    var span = new Span(7, 0, false),
        pos = 0, cleanLine = false, cjk = false;
    
    result += "<div class='line'>";
    
    for (; i < data.length; i++) {
        // Special color
        if (pos == 0) {
            var ch = data.substr(i, 2);
            if (ch == "\xa1\xb0") {
                // ※
                cleanLine = true;
                span.reset();
                span.f = 2;
            } else if (ch == ": ") {
                // : 
                cleanLine = true;
                span.reset();
                span.f = 6;
            }
        }
        if (data[i] == "\x1b") {
            // ESC
            var span2 = extractColor(data, i, span);
            if (!span2) {
                span.text += data[i];
                pos++;
            } else if (cjk && data[span2.i] != "\n") {
                span.text += data[span2.i];
                span.halfEnd = true;
                
                result += span.toString();
                
                span2.text += span.text.substring(span.text.length - 2);
                span2.halfStart = true;
                
                pos++;
                i = span2.i;
                span = span2;
                cjk = false;
            } else {
                cjk = false;
                result += span.toString();
				if (span2.i <= i) {
					throw new Error("bbs-reader crashed! infinite loop");
				}
                i = span2.i - 1;
                span = span2;
            }
        } else if (data[i] == "\r" && data[i + 1] == "\n") {
            continue;
        } else if (data[i] == "\r" || data[i] == "\n") {
            result += span.toString() + "</div><div class='line'>";
            span.text = "";
            span.halfStart = false;
            span.halfEnd = false;
            cjk = false;
            
            if (cleanLine) {
                span.reset();
                cleanLine = false;
            }
            
            pos = 0;
        } else {
            if (cjk) {
                cjk = false;
            } else if (data.charCodeAt(i) & 0x80) {
                cjk = true;
            }
            span.text += data[i];
            pos++;
        }
    }
    
    result += span.toString() + "</div>";
    
    return {
        html: result,
        title: title,
        author: author,
        time: time
    };
}
function bbsReader(data) {
    var i = 0, match, result = "";
        
    var author, title, time, label, board;
    
    if ((match = /^(\xa7@\xaa\xcc:.*)\n(.*)\n(.*)\n/.exec(data))) {
        // draw header    
        author = stripColon(match[1]);
        title = stripColon(match[2]);
        time = stripColon(match[3]);
        
        // find board
        var t = splitLabel(author);
        author = t[0];
        label = t[1];
        board = t[2];
        
        // 作者
        result += makeHead("\xa7@\xaa\xcc", author, label, board);
        // 標題
        result += makeHead("\xbc\xd0\xc3D", title);
        // 時間
        result += makeHead("\xae\xc9\xb6\xa1", time);
        
        // ─
        result += "<div class='line'><span class='f6'>" + "\xa2w".repeat(39) + "</span></div>";
        
        i += match[0].length;
    }
    
    var span = new Span(7, 0, false),
        pos = 0, cleanLine = false, cjk = false;
    
    result += "<div class='line'>";
    
    for (; i < data.length; i++) {
        // Special color
        if (pos == 0) {
            var ch = data.substr(i, 2);
            if (ch == "\xa1\xb0") {
                // ※
                cleanLine = true;
                span.reset();
                span.f = 2;
            } else if (ch == ": ") {
                // : 
                cleanLine = true;
                span.reset();
                span.f = 6;
            }
        }
        if (data[i] == "\x1b") {
            // ESC
            var span2 = extractColor(data, i, span);
            if (!span2) {
                span.text += data[i];
                pos++;
            } else if (cjk && data[span2.i] != "\n") {
                span.text += data[span2.i];
                span.halfEnd = true;
                
                result += span.toString();
                
                span2.text += span.text.substring(span.text.length - 2);
                span2.halfStart = true;
                
                pos++;
                i = span2.i;
                span = span2;
                cjk = false;
            } else {
                cjk = false;
                result += span.toString();
				if (span2.i <= i) {
					throw new Error("bbs-reader crashed! infinite loop");
				}
                i = span2.i - 1;
                span = span2;
            }
        } else if (data[i] == "\r" && data[i + 1] == "\n") {
            continue;
        } else if (data[i] == "\r" || data[i] == "\n") {
            result += span.toString() + "</div><div class='line'>";
            span.text = "";
            span.halfStart = false;
            span.halfEnd = false;
            cjk = false;
            
            if (cleanLine) {
                span.reset();
                cleanLine = false;
            }
            
            pos = 0;
        } else {
            if (cjk) {
                cjk = false;
            } else if (data.charCodeAt(i) & 0x80) {
                cjk = true;
            }
            span.text += data[i];
            pos++;
        }
    }
    
    result += span.toString() + "</div>";
    
    return {
        html: result,
        title: title,
        author: author,
        time: time
    };
}
function bbsReader ( data ) { var i = 0 , match , result = "" ; var author , title , time , label , board ; if ( ( match = / ^(\xa7@\xaa\xcc:.*)\n(.*)\n(.*)\n / . exec ( data ) ) ) { // draw header     author = stripColon ( match [ 1 ] ) ; title = stripColon ( match [ 2 ] ) ; time = stripColon ( match [ 3 ] ) ; // find board var t = splitLabel ( author ) ; author = t [ 0 ] ; label = t [ 1 ] ; board = t [ 2 ] ; // 作者 result += makeHead ( "\xa7@\xaa\xcc" , author , label , board ) ; // 標題 result += makeHead ( "\xbc\xd0\xc3D" , title ) ; // 時間 result += makeHead ( "\xae\xc9\xb6\xa1" , time ) ; // ─ result += "<div class='line'><span class='f6'>" + "\xa2w" . repeat ( 39 ) + "</span></div>" ; i += match [ 0 ] . length ; } var span = new Span ( 7 , 0 , false ) , pos = 0 , cleanLine = false , cjk = false ; result += "<div class='line'>" ; for ( ; i < data . length ; i ++ ) { // Special color if ( pos == 0 ) { var ch = data . substr ( i , 2 ) ; if ( ch == "\xa1\xb0" ) { // ※ cleanLine = true ; span . reset ( ) ; span . f = 2 ; } else if ( ch == ": " ) { // :  cleanLine = true ; span . reset ( ) ; span . f = 6 ; } } if ( data [ i ] == "\x1b" ) { // ESC var span2 = extractColor ( data , i , span ) ; if ( ! span2 ) { span . text += data [ i ] ; pos ++ ; } else if ( cjk && data [ span2 . i ] != "\n" ) { span . text += data [ span2 . i ] ; span . halfEnd = true ; result += span . toString ( ) ; span2 . text += span . text . substring ( span . text . length - 2 ) ; span2 . halfStart = true ; pos ++ ; i = span2 . i ; span = span2 ; cjk = false ; } else { cjk = false ; result += span . toString ( ) ; if ( span2 . i <= i ) { throw new Error ( "bbs-reader crashed! infinite loop" ) ; } i = span2 . i - 1 ; span = span2 ; } } else if ( data [ i ] == "\r" && data [ i + 1 ] == "\n" ) { continue ; } else if ( data [ i ] == "\r" || data [ i ] == "\n" ) { result += span . toString ( ) + "</div><div class='line'>" ; span . text = "" ; span . halfStart = false ; span . halfEnd = false ; cjk = false ; if ( cleanLine ) { span . reset ( ) ; cleanLine = false ; } pos = 0 ; } else { if ( cjk ) { cjk = false ; } else if ( data . charCodeAt ( i ) & 0x80 ) { cjk = true ; } span . text += data [ i ] ; pos ++ ; } } result += span . toString ( ) + "</div>" ; return { html : result , title : title , author : author , time : time } ; }
convert ansi string into html
convert ansi string into html