逐行解析,然后从jquery中的textarea逐字逐句解析

时间:2017-05-27 20:37:54

标签: javascript jquery parsing

我正在为html解析器创建一个基本的.fountain编辑器,它几乎检查了keyup上textarea中输入的单词。

逐行解析在下面工作,但当然用户会在一行中输入“** bold ** then * italic *”,但我似乎无法让它扫描一行中的每个单词。 / p>

以下是我的代码:

jQuery.fn.parseAsFountain = function( window, jQuery ){
    jQuery = $;
    var storybox = $(this).val();
    story = storybox.split('\n');


    // Process The entire box

    for( var i=0;i<story.length;i++ ){

        var line = story[i];

        SubstitutePerLine(line);


    }

    story_cleared = story.join('\n');
    story_breaks = story_cleared.replace(/(?:\r\n|\r|\n)/g, '<br />');
    return story_breaks;

    function SubstitutePerLine(line){

        if( line.match(/^[*].*[*]$/) ){ 
            newval = line.slice(1, -1);

            if( newval.match(/^[*].*[*]$/) ){ 
                newval2 = newval.slice(1, -1);

                if( newval2.match(/^[*].*[*]$/) ){ 
                    newval3 = newval2.slice(1, -1);

                    if( newval3.match(/\\/) ) {
                        if(newval3.match(/\\\*/)){
                        slash_val = newval3.replace(/\\/, '');
                        story[i] = '<b><i>' + slash_val + '</i></b>';
                        }
                        else {
                        story[i] = '<b><i>' + newval3 + '</i></b>';
                        }
                    }

                    else {
                    story[i] = '<b><i>' + newval3 + '</i></b>';
                    }

                }

                else if( newval2.match(/\\/) ) {
                    if(newval2.match(/\\\*/)){
                    slash_val = newval2.replace(/\\/, '');
                    story[i] = '<b>' + slash_val + '</b>';
                    }
                    else {
                    story[i] = '<b>' + newval2 + '</b>';
                    }
                }

                else {
                story[i] = '<b>' + newval2 + '</b>';
                }

            }

            else if( newval.match(/\\/) ) {
                if(newval.match(/\\\*/)){
                slash_val = newval.replace(/\\/, '');
                story[i] = '<i>' + slash_val + '</i>';
                }
                else {
                story[i] = '<i>' + newval + '</i>';
                }
            }

            else {
                story[i] = '<i>' + newval + '</i>';
            }

        }


        if( line.match(/#/) ){
            newval = line.replace(/^#/, '');
            story[i] = '<p hidden>' + newval + '</p>';
        }
        if( line.match(/##/) ){
            newval = line.replace(/^##/, '');
            story[i] = '<p hidden>' + newval + '</p>';
        }
        if( line.match(/###/) ){
            newval = line.replace(/^###/, '');
            story[i] = '<p hidden>' + newval + '</p>';
        }

    return story;

    }



}

我尝试在循环内的另一个分割(“”)中逐字重新拆分,然后再次加入它但无济于事。

1 个答案:

答案 0 :(得分:1)

解析标记不是一项简单的任务。仅举几例:

  • 如果星号后跟一个空格,则它不会是格式化文本的开头;
  • 可以在一行中格式化多个部分,不仅包括单个单词,还包括单词组;
  • 格式化甚至可以跨越换行符。
  • 星号前面可能有偶数个斜杠,在这种情况下星号转义。

这是一个只处理斜体,粗体和斜体+粗体格式以及删除转义斜杠的解决方案。我没有处理哈希(#),因为对于Q&amp; A来说这已经相当宽泛了:

&#13;
&#13;
jQuery.fn.parseAsFountain = function() {
    var txt = this.val(),
        re = /(\s?)(\\*)(\*+)(?=(\s?))/g,
        arr,
        openAsterisks = 0,
        result = [],
        last = 0,
        start;
    while ((arr = re.exec(txt)) !== null) {
        var [all, prefix, escaped, asterisks, suffix] = arr;
        if (escaped.length % 2) { // First asterisk is escaped
            escaped += asterisks[0];
            asterisks = asterisks.substr(1);
            if (!asterisks.length) continue; // Nothing to do
        }
        var useAsterisks = 0;
        if (openAsterisks && !prefix.length) {
            useAsterisks = Math.min(openAsterisks, asterisks.length);
            // Add HTML for bold, italic or both
            result.push(
                txt.substr(last, start - useAsterisks - last),
                ['<i>','<b>','<i><b>'][useAsterisks-1],
                txt.substr(start, arr.index + escaped.length - start),
                ['</i>','</b>','</b></i>'][useAsterisks-1]);
            last = arr.index + escaped.length + useAsterisks;
            openAsterisks = 0;
        }
        if (!openAsterisks && asterisks.length > useAsterisks && !suffix.length) {
            openAsterisks = asterisks.length - useAsterisks;
            start = arr.index + prefix.length + escaped.length + asterisks.length;
        }
    }
    // Flush remaining text
    result.push(txt.substr(last));
    // Remove escaping slashes (not escaped ones!):
    result = result.join('').replace(/\\(.)/g, '$1');
    return result;
}

$('textarea').on('input', function () {
    $('pre').html($(this).parseAsFountain());
}).trigger('input');
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea style="width:100%" rows=5>
This is **a** test *with several* ***formats 
but*** keeping asterisks \*where* needed.
</textarea>
<h3>Rendered:</h3>
<pre>
</pre>
&#13;
&#13;
&#13;