预处理较少以允许空白敏感语法

时间:2015-01-21 17:52:04

标签: javascript regex less

我正在查看github issue in less project试图允许空格敏感而不是类似于手写笔的大括号。

我开始(非常野蛮地)将可能的建议解决方案混合在一起,这样就可以将even-less(空白敏感版本更少)预处理为更少的解析器,然后可以像往常一样解析。



// make input string
var src = [
".navbar",
"  display:block;",
"  .item",
"    float:left;",
"    text-decoration:none;",
"    &:hover",
"      text-decoration:underline;"
].join("\n")

function parseEvenLess(src){

    // split intput string into lines
    var lines = src.split("\n");

    // declare variables to handle output, and tracking of indents
    var out = [], lastIndent = "", currentIndent = "", extras = [];

    // loop through lines, then each indent added during loop
    for(var i = 0; i < lines.length + extras.length; i++){
        // get the current line (from lines or added indents)
        var line = lines[i] || extras[i-lines.length];
        // get the current indentation string
        currentIndent = line.match(/^\s*/)[0];
        // attempt to handle ommision of `:` and `;`
        // must be done retrospectively (on previous line) to disambiguate `element:right` as selector or rule definition
        if(i && currentIndent.length <= lastIndent.length){
            out[i-1] = out[i-1].replace(/^(\s*[^\s:]+)(\s*:\s*|\s+)(\S[^;]+);?$/g, "$1: $3;");
        }
        // if we have increased the indentation
        if(lastIndent.length < currentIndent.length){
            // add an opening brace
            out[i-1] += " {";
            // slip the indent onto the indentations array to handle insertion of closing braces
            extras.unshift(lastIndent);
        }
        // if we have decreased indentation
        if(lastIndent.length > currentIndent.length){
            // prepend the line with a closing brace (indented)
            line = currentIndent+"}" + line;
        }
        // add the line to the final output array
        out.push(line);
        // store reference to currentIndent for use in next iteration
        lastIndent = currentIndent;
    }

    // return the final string
    return out.join("\n");

}

var finalOutput = [];

// works with single block
finalOutput.push( parseEvenLess([
".navbar",
"  display:block;",
"  .item",
"    float:left;",
"    text-decoration:none;",
"    &:hover",
"      text-decoration:underline;"
].join("\n")) );

// breaks with multiple blocks
// Uncaught TypeError: Cannot read property 'match' of undefined
finalOutput.push( parseEvenLess([
".navbar",
"  display:block;",
"  .item",
"    float:left;",
"    text-decoration:none;",
"    &:hover",
"      text-decoration:underline;",
".navbar",
"  display:block;",
"  .item",
"    float:left;",
"    text-decoration:none;",
"    &:hover",
"      text-decoration:underline;"
].join("\n")) );

document.getElementById("out").innerText = finalOutput.join("\n\n...\n\n");
&#13;
<pre id="out"></pre>
&#13;
&#13;
&#13;

我的解决方案,除了从头到尾都是一个可怕的黑客攻击,当有多个块时会中断。我真的不想为已经很难解决这个问题添加更多黑客攻击 - 我相信还有一个更优雅的解决方案 - 也许某种递归函数意识到它当前的缩进而不是跟踪和引用前一行...或者可能是两遍方法,首先将输入组织成块和缩进组,然后在第二遍中循环它们。

如何解决此问题以获得更强大的解决方案。

0 个答案:

没有答案