2016-09-16 43 views
0

我一直在为Velocity的一个稍微修改过的版本研究语法突出显示。简而言之,我可以如何包装从#inline()开始并以相应的#end结尾的所有内容,条件是可以存在总是有#end的0-无限if语句。如果您有任何问题,请告诉我。将一个JavaScript生成的HTML结构包含在多个终点实例中

可在此fiddle上找到示例。请参阅下面的更多详细信息。

样本HTML

小提琴显示的JavaScript修改HTML以下版本的职务。

<pre><code> 
$javascript.push("/path/to/file") 
#inline() 
    $('.lazy.bg2').attr({'data-src':'/img_path2.jpg'}).css('background','red'); 
    #if($myVar == "hi") 
     $('.someClass).hide() 
    #elseif($myVar == "there") 
     $('.lazy.bg1').attr({'data-src':'/img_path.jpg'}) 
    #else 
     $('.lazy.bg3').attr({'data-src':'/img_path3.jpg'}) 
    #end 
    $('.lazy.bg2 a').attr({'data-href':'/random-path2.htm'}) 
    $('.lazy.bg1 a').attr({'data-href':'/random-path.htm'}) 
#end 

#if($test.method == "myVal") 
    #set($foo = "swag") 
#elseif($foo == "bar") 
    #set($foo = "ballin") 
#elseif($myObject.randomMethod().contains("myVal")) 
    #set($foo = "weeee") 
#else 
    #set($foo = "sad days") 
#end 
#set($testVar = "Test value") 
#parse("/path/to/file")</code></pre> 

的问题

因为有我不知道如何得到它的结束#inline()语句相匹配的#end多个实例。主要的问题在于可能有无数的if语句,但#inline()将始终具有相应的结束语句。所以我猜猜最好的方法是基于它是相同的空白级别来匹配它。不过,我不确定是否有更好的解决方案。我在Gone Coding'shere找到原始的javascript。不过,我稍微修改了它以更好地匹配我的实现。 注意我在早期的jQuery语句中将速度类添加到<pre>最终结果应该只应用<span>#inline()内的jQuery。

的Javascript

$('pre.velocity code').each(function() { 
    var open = false; 
    var result = $(); 
    $(this).contents().each(function() { 
     var $this = $(this); 
     if ($this.text() == "#inline()" || $this.text() == "#end") { 
      if (open) { 
       result.wrapAll('<span class="velocity-inline-inner"></span>'); 
       open = false; 
      } else { 
       result = $(); 
       open = true; 
      } 
     } else { 
      result = result.add($this) 
     } 
    }); 
    if (open) { 
     result.wrapAll('<span class="velocity-inline-inner"></span>'); 
    } 
}); 

更新的Javascript

我有一个可以依靠的空白,并选择相匹配的#inline()的空白水平#end以下,不过我有问题在if语句中仅将该子字符串转换为html。

$('pre.velocity code').each(function(){ 
    var str = $(this).text(); 
    str = str.substring(str.indexOf("#inline()") + 10); 
    textArray = str.split("\n"); 
    getInlineEnd(str,textArray); 
}); 

function getInlineEnd(str,textArray) { 
    for(var i = 0; i <= textArray.length; i++) { 
     if(textArray[i].length === 4 && textArray[i] === "#end") { 
     //convert textArray[i] to a html node and then wrap with a <span> 
     break; 
     } 
    } 
} 

最终目标HTML

最终的结果应该看起来像下面。我已经在#inline()#end之间添加了一个范围。

#inline() 
<span class="velocity-inline-inner"> 
    $('.lazy.bg2').attr({'data-src':'/img_path2.jpg'}).css('background','red'); 
    #if($myVar == "hi") 
     $('.someClass).hide() 
    #elseif($myVar == "there") 
     $('.lazy.bg1').attr({'data-src':'/img_path.jpg'}) 
    #else 
     $('.lazy.bg3').attr({'data-src':'/img_path3.jpg'}) 
    #end 
    $('.lazy.bg2 a').attr({'data-href':'/random-path2.htm'}) 
    $('.lazy.bg1 a').attr({'data-href':'/random-path.htm'}) 
</span> 
#end 

我相信,一旦我得到上面的代码正常工作,那么它应该适当的语法突出显示。但最终目标是让所有jQuery方法值突出显示。我将在不同的正则表达式下处理选择器。

回答

0

我落得这样做下面的JS和HTML来包装#inline()和基于空白相应#end。这是fiddle提供的html。

// Loop thorugh each of the velocity and see if there is an inline to syntax highlight. 
 
    $('pre.velocity code').each(function(){ 
 
     var html = $(this).html(); 
 
     var str = html.toString(html); // convert html object to a string 
 
     str = str.substring(str.indexOf("#inline()") + 17); // split the string so only take half of it. 
 
     var textArray = str.split("\n"); // split the array on a new line 
 
     var newHtml = getInlineEnd(textArray); 
 
     regExVelocity($(this),str,newHtml); // replace the string 
 
    }); 
 

 
    /** 
 
    * Loops through the inline and finds the #end based on white-space 
 
    * @param textArray 
 
    * @type Array 
 
    * @returns {string|*} 
 
    */ 
 
    function getInlineEnd(textArray) { 
 
     // loop through each line of the string. 
 
     for(var i = 0; i <= textArray.length; i++) { 
 
      if(i == 0) { 
 
       // first line in #inline() 
 
       textArray[i] = "<span class=\"velocity-inline-inner\">"+textArray[i] 
 
      } 
 
      if(undefined !== textArray[i] && textArray[i].length === 38 && textArray[i] === "<span class=\"velocity-end\">#end</span>") { 
 
       // Found the end of the #inline() based on white-space. Update the text. 
 
       textArray[i] = textArray[i].replace(textArray[i],'</span><span class="velocity-end">#end</span>'); 
 
       // break out of the for loop since we got the value 
 
       break; 
 
      } 
 
     } 
 
     // return the string and reformat it. 
 
     return textArray.join('\n'); 
 
    } 
 

 
    /** 
 
    * Runs regex for velocity syntax highlighting uses .html() if you want to use the text then use regExText 
 
    * @param selector 
 
    * @param regex 
 
    * @param output 
 
    */ 
 
    function regExVelocity(selector, regex, output) { 
 
     selector.html(function(i, html) { 
 
      return(html.replace(regex, output)); 
 
     }); 
 
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<pre class="velocity"><code> 
 
<span class="velocity-object">$javascript</span>.push(<span class="velocity-string">"/path/to/file"</span>) 
 
<span class="velocity-inline">#inline()</span> 
 
    $('.lazy.bg2').attr({'data-src':'/img_path2.jpg'}).css('background','red'); 
 
    <span class="velocity-if">#if(</span><span class="velocity-if-inner">$myVar == "hi"</span><span class="velocity-if">)</span> 
 
    #elseif($myVar == "there") 
 
      $('.lazy.bg1').attr({'data-src':'/img_path.jpg'}) 
 
    #else 
 
      $('.lazy.bg3').attr({'data-src':'/img_path3.jpg'}) 
 
    <span class="velocity-end">#end</span> 
 
    $('.lazy.bg1 a').attr({'data-href':'/random-path.htm'}) 
 
<span class="velocity-end">#end</span> 
 
<span class="velocity-if">#if(</span><span class="velocity-if-inner"><span class="velocity-object">$test</span>.method == "myVal"</span><span class="velocity-if">)</span> 
 
    <span class="velocity-set">#set(</span><span class="velocity-inner"><span class="velocity-variable">$foo </span><span class="equalSign">=</span> "swag"</span><span class="velocity-set">)</span> 
 
#elseif($foo == "bar") 
 
    <span class="velocity-set">#set(</span><span class="velocity-inner"><span class="velocity-variable">$foo </span><span class="equalSign">=</span> "ballin"</span><span class="velocity-set">)</span> 
 
#elseif(<span class="velocity-object">$myObject</span>.randomMethod().contains(<span class="velocity-string">"myVal"</span>)) 
 
    <span class="velocity-set">#set(</span><span class="velocity-inner"><span class="velocity-variable">$foo </span><span class="equalSign">=</span> "weeee"</span><span class="velocity-set">)</span> 
 
#else 
 
    <span class="velocity-set">#set(</span><span class="velocity-inner"><span class="velocity-variable">$foo </span><span class="equalSign">=</span> "sad days"</span><span class="velocity-set">)</span> 
 
<span class="velocity-end">#end</span> 
 
<span class="velocity-set">#set(</span><span class="velocity-inner"><span class="velocity-variable">$testVar </span><span class="equalSign">=</span> "Test value"</span><span class="velocity-set">)</span> 
 
<span class="velocity-parse">#parse(</span><span class="velocity-parse-path">"/path/to/file"</span><span class="velocity-parse">)</span></code></pre>

0

我快速查看了你的代码,但它有点野兽。所以我会给出一个更全面的概述。首先,您需要能够解析(某种程度上)输入的某些部分(对于此#inline,#if和#end)。然后,您需要计算#end关闭的开口数量。然后,当每个#结束时,您检查列表中的最新开放。当你到达将关闭#inline开头的#end时,这就是关闭</span>的地方。

注:我没有测试过代码。我不知道代码原本是如何工作的,等等。我只是用它作为伪代码来展示你需要做什么样的事情。

$('pre.velocity code').each(function() { 
    var open = []; 
    var result = $(); 
    $(this).contents().each(function() { 
     var $this = $(this); 
     if ($this.text() == "#inline()" || $this.text().substr("#if(") === 0) { 
      open.push($this); 
     } 
     else if ($this.text() == "#end") { 
      var toClose = open.pop(); 
      if (toClose.text() === "#inline()") { 
       // wrap from after #inline() to before #end 
      } 
     } 
    }); 
}); 
+0

结束了说,有一个TypeError它不能读取的不确定text属性,并指向'如果(toClose.text()=== “#inline()” ){'。所以听起来像pop()没有返回带有文本节点的对象。 – Elias

+0

哦对。最好做一些调试呢?正如我所说,我并不完全了解你的代码,所以代码可能不会只是复制/粘贴。 – Whothehellisthat

相关问题