将 javascript 生成的 html 结构包装在具有多个端点实例的跨度中
Wrap a javascript generated html structure in a span with multiple instances of the end point
我一直在为 Velocity 的略微修改版本开发语法荧光笔。简而言之,我如何包装所有从 #inline()
开始并以相应的 #end
结束的内容,条件是可以有 0 无限的 if 语句,这些语句总是有一个 #end
。如果您有任何问题,请告诉我。
可以在此 fiddle 上找到示例。请参阅下面的详细信息。
样本HTML
fiddle 显示 post 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>
问题
因为 #end
有多个实例,所以我不确定如何让它与 #inline()
语句的结尾相匹配。主要问题是可能有无数个 if 语句,但 #inline()
总是有相应的 end 语句。所以我猜最好的方法是根据它是相同的 white-space 级别来匹配它。但是我不确定是否有更好的解决方案。我在 Gone Coding's post here 中找到了原来的 javascript。但是我稍微修改了它以更好地匹配我的实现。 请注意,我在之前的 jQuery 语句中将速度 class 添加到 <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
我有以下可以计算白色 space 并选择与 #inline()
的白色 space 级别相匹配的 #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 方法值突出显示。我将在不同的正则表达式下处理选择器。
我快速浏览了您的代码,但它有点像野兽。所以我会给出一个更一般的概述。首先,您需要能够(在某种程度上)解析输入的某些部分(为此,#inline、#if 和#end)。然后您需要计算将以#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
}
}
});
});
我最后做了下面的 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>
我一直在为 Velocity 的略微修改版本开发语法荧光笔。简而言之,我如何包装所有从 #inline()
开始并以相应的 #end
结束的内容,条件是可以有 0 无限的 if 语句,这些语句总是有一个 #end
。如果您有任何问题,请告诉我。
可以在此 fiddle 上找到示例。请参阅下面的详细信息。
样本HTML
fiddle 显示 post 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>
问题
因为 #end
有多个实例,所以我不确定如何让它与 #inline()
语句的结尾相匹配。主要问题是可能有无数个 if 语句,但 #inline()
总是有相应的 end 语句。所以我猜最好的方法是根据它是相同的 white-space 级别来匹配它。但是我不确定是否有更好的解决方案。我在 Gone Coding's post here 中找到了原来的 javascript。但是我稍微修改了它以更好地匹配我的实现。 请注意,我在之前的 jQuery 语句中将速度 class 添加到 <pre>
。 最终结果应该仅应用 <span>
到 #inline()
.
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
我有以下可以计算白色 space 并选择与 #inline()
的白色 space 级别相匹配的 #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 方法值突出显示。我将在不同的正则表达式下处理选择器。
我快速浏览了您的代码,但它有点像野兽。所以我会给出一个更一般的概述。首先,您需要能够(在某种程度上)解析输入的某些部分(为此,#inline、#if 和#end)。然后您需要计算将以#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
}
}
});
});
我最后做了下面的 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>