基于javascript的自定义代码编辑器的缩进

时间:2019-02-15 10:35:49

标签: javascript html regex

我正在为自己创建的语言制作自定义代码编辑器。到目前为止,我已经使用javascriprt span类实现了语法高亮显示。现在,我想在IF ELSE嵌套循环前面添加适当的间距或制表符空间。我对javascript不太满意。

以下是我到目前为止编写的代码。

<!DOCTYPE html>
<html>
    <body>

        <style>
            .code-str { color: #008000; }
            .code-elem{ color: #ff0000;}
            .code-comment { color: #0000FF; }
        </style>



<textarea rows="20" cols="100" type="text" id="text2">Code to test

###VAR:837:Single###

###IF:69154!=1###

###IF:69154!=1###

    ###VAR:69154:Single###x

###ENDIF:69154###

    ###VAR:69154:Single###x

###ENDIF:69154###

###VAR:990:Single### battery ###VAR:S301:Single###mAh (###VAR:S302:Single###V) 

###IFLISTING:7785###

    replaces

###ENDIFLISTING:7785###

###IFLISTING:7786###

    replaces

###ENDIFLISTING:7786###


Paste this code in the textarea below and see the magic </textarea>

        <textarea rows="20" cols="100" type="text" id="text1"></textarea>

        <button onclick="myFunction()">MAGIC</button>

        <script>
            function myFunction() {



                var str = document.getElementById("text1").value;

                str = str.replace(/###IF(.*?)###/g, '<span class="code-elem"></br> </br>###IF$1### </br></span>'); 
                str = str.replace(/###ENDIF(.*?)###/g, '<span class="code-elem"></br> ###ENDIF$1### </br></span>');
                str = str.replace(/###IFLISTING(.*?)###/g, '<span class="code-str">  ###IFLISTING$1### </span>');
                str = str.replace(/###ENDIFLISTING(.*?)###/g, '<span class="code-str">###ENDIFLISTING$1### </span>');
                str = str.replace(/###VAR(.*?)###/g, '<span class="code-comment"> ###VAR$1### </span>');
                 str = str.replace(/###LISTING(.*?)###/g, '<span class="code-comment">  ###LISTING$1### </span>');

                document.getElementById("demo").innerHTML = str;
            }
        </script>


        <p id="demo"></p>
    </body>
</html>

This is the output of the code

现在我想要的是嵌套的IF ELSE循环应以适当的缩进清晰显示。 我心里有些粗略的看法。我想我应该使用一个FOR循环,然后使用一个计数器来增加IF和ELSE计数。但是我不知道该怎么做。谁能给我一个主意?

我将非常感谢最小的帮助或建议。

1 个答案:

答案 0 :(得分:0)

您不仅必须迭代所有具有匹配关键字的行,而且还必须保持当前缩进,然后对所有行进行迭代,对于某些关键字,该行将增加,而对于其他某些关键字,则将其减少。我会将这种缩进影响作为每个关键字的属性存储在它们的样式属性旁边:

const keywords = {
    IF: { style: "code-elem", indent: 4 },
    ENDIF: { style: "code-elem", indent: -4 },
    IFLISTING: { style: "code-str", indent: 4 },
    ENDIFLISTING: { style: "code-str", indent: -4 },
    VAR: { style: "code-comment", indent: 0 },
    LISTING: { style: "code-comment", indent: 0 } 
};

function myFunction() {
    let indent = 0;
    document.getElementById("demo").innerHTML = document.getElementById("text1").value.split(/[\r\n]+/).map(line => {
        const oldIndent = indent;
        line = line.trim().replace(/###([A-Z]+)(.*?)###/g, (m, keyword, arg) => {
            const param = keywords[keyword];
            if (!param) return m;
            indent += param.indent;
            return `<span class="${param.style}">${m}</span>`;
        });
        return "&nbsp;".repeat(Math.min(indent, oldIndent)) + line;
    }).join("<br>");
}
.code-str     { color: #080; }
.code-elem    { color: #f00;}
.code-comment { color: #00f; }
<textarea rows="15" cols="80" type="text" id="text1">###VAR:837:Single###
###IF:69154!=1###
###IF:69154!=1###
 ###VAR:69154:Single###x
###ENDIF:69154###
    ###VAR:69154:Single###x
###ENDIF:69154###
###VAR:990:Single### battery ###VAR:S301:Single###mAh (###VAR:S302:Single###V) 
###IFLISTING:7785###
       replaces
   ###ENDIFLISTING:7785###
###IFLISTING:7786###
    replaces
###ENDIFLISTING:7786###
</textarea><br>
<button onclick="myFunction()">MAGIC</button>
<p id="demo"></p>