2016-09-16 39 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

相關問題