2017-02-13 62 views
0

我试图解析W3c API JSON输出,javascript和我被困在如何某些跨度放置一些关键字里面,因为它们的列(它们在字符串中的位置)如何突出显示多个项目的位置?

我已经重新组织了PHP的消息,因此

$.each(data.messages,function(line,msgs) { 
     content = $("#l"+line).text(); 
     offset = 0; 

     $.each(msgs,function(i,v) { 
      position = v.firstColumn+v.hiliteStart+offset; 
      length = v.hiliteLength; 

      if (isNaN(position)) { 
       position = v.lastColumn+v.hiliteStart; 
      } 

      content = content.substr(0, position)+'[span]'+content.substr(position, length)+'[/span]'+content.substr(position + length); 
      offset += 13; //offset compensates for [span] and [/span] 
     }); 
     //htmlentites function from locutus.io 
     nst = htmlentities(content); 
     nst = nst.replace(/\[span\]/g,'<span>'); 
     nst = nst.replace(/\[\/span\]/g,'</span>'); 
     $("#l"+line).html(nst); 

     }); 

我在这里的目标是相同的HTML代码行中重点介绍了一些错误和警告:我的东西,用下面的读取结束。

+0

你试过[mark.js(https://markjs.io/)? – dude

+0

是的,我做过了,但没有按行列标记(或者我错过了文档中的那部分) – user2374726

回答

0

我会从定义高亮范围作为对象开始,然后从那里开始工作。例如,

ranges = [{ 
    "begin": 145, 
    "end": 155 
    }, { 
    "begin": 4, 
    "end": 18 
    }, { 
    "begin": 4, 
    "end": 18 
    }, { 
    "begin": 90, 
    "end": 102 
    }, { 
    "begin": 4, 
    "end": 41 
    }]; 

无论这些都是你的JS中定义,或者如果它们来自服务器API是由你和你如何设计程序。但是,一旦你有了这些定义,创建一个函数,将您的原始字符串和这个范围的集合,并打破你的字符串(最好使用slice)到一个字符串段的集合。然后,您可以遍历您的细分,并根据需要附加<span></span>,然后将最终字符串放入DOM中。我无法从你的代码中得知你从哪里得到你的索引。但是如果你能把它们放在这样一个干净的结构中,那么你可以干净地打破你的弦乐。

在这里要记住的一件事是,你可以有重叠跨度。如果发生这种情况,你需要将你的范围变平。这里有一组函数可以让你得到你所需要的。请致电createHighlightedString,并附上您的文字和高亮范围列表。如有必要,它会将您的范围变平,并给您一个清晰的结果。在这个底部有一个到工作样品的链接。

//Your implementation would look "something" like this 
nst = htmlentities(content); 
var ranges = [];//??? - GET YOUR RANGES DEFINED CLEANLY HERE 
var highlightedString = createHighlightedString(ranges,nst); 
$("#l"+line).html(highlightedString); 

function createHighlightedString(ranges, text) { 
    var flatRanges = flattenRanges(ranges); 
    var inflatedRanges = inflateRanges(flatRanges, text.length); 
    var filledRanges = fillRanges(inflatedRanges, text); 
    var str = ""; 
    var index = 0; 
    for (var i in filledRanges) { 
    var range = filledRanges[i]; 
    var begin = range.begin, end = range.end; 
    if (range.count > 0) { 
     str += "<span class='highlight'>" + range.text + "</span>"; 
    } else { 
     str += range.text; 
    } 
    } 
    return str; 
} 

function flattenRanges(ranges) { 
    var points = []; 
    var flattened = []; 
    for (var i in ranges) { 
    if (ranges[i].end < ranges[i].begin) { //RE-ORDER THIS ITEM (BEGIN/END) 
     var tmp = ranges[i].end+1; //RE-ORDER BY SWAPPING 
     ranges[i].end = ranges[i].begin; 
     ranges[i].begin = tmp; 
    } 
    points.push(ranges[i].begin); 
    points.push(ranges[i].end); 
    } 
    //MAKE SURE OUR LIST OF POINTS IS IN ORDER 
    points.sort(function(a, b){return a-b}); 
    //FIND THE INTERSECTING SPANS FOR EACH PAIR OF POINTS (IF ANY) 
    //ALSO MERGE THE ATTRIBUTES OF EACH INTERSECTING SPAN, AND INCREASE THE COUNT FOR EACH INTERSECTION 
    for (var i in points) { 
    if (i==0 || points[i]==points[i-1]) continue; 
    var includedRanges = ranges.filter(function(x){ 
     return (Math.max(x.begin,points[i-1]) < Math.min(x.end,points[i])); 
    }); 
    if (includedRanges.length > 0) { 
     var flattenedRange = { 
     begin:points[i-1], 
     end:points[i], 
     count:0 
     } 
     for (var j in includedRanges) { 
     var includedRange = includedRanges[j]; 
     for (var prop in includedRange) { 
      if (prop != 'begin' && prop != 'end') { 
      if (!flattenedRange[prop]) flattenedRange[prop] = []; 
      flattenedRange[prop].push(includedRange[prop]); 
      } 
     } 
     flattenedRange.count++; 
     } 
     flattened.push(flattenedRange); 
    } 
    } 
    return flattened; 
} 

function inflateRanges(ranges, length=0) { 
    var inflated = []; 
    var lastIndex; 
    for (var i in ranges) { 
    if (i==0) { 
     //IF THERE IS EMPTY TEXT IN THE BEGINNING, CREATE AN EMPTY RANGE 
     if (ranges[i].begin > 0){ 
     inflated.push({ 
      begin:0, 
      end:ranges[i].begin-1, 
      count:0 
     }); 
     } 
     inflated.push(ranges[i]); 
    } else { 
     if (ranges[i].begin == ranges[i-1].end) { 
     ranges[i-1].end--; 
     } 
     if (ranges[i].begin - ranges[i-1].end > 1) { 
     inflated.push({ 
      begin:ranges[i-1].end+1, 
      end:ranges[i].begin-1, 
      count:0 
     }); 
     } 
     inflated.push(ranges[i]); 
    } 
    lastIndex = ranges[i].end; 
    } 
    //FOR SIMPLICITY, ADD ANY REMAINING TEXT AS AN EMPTY RANGE 
    if (lastIndex+1 < length-1) { 
    inflated.push({ 
     begin:lastIndex+1, 
     end:length-1, 
     count:0 
    }) 
    } 
    return inflated; 
} 

function fillRanges(ranges, text) { 
    for (var i in ranges) { 
    ranges[i].text = text.slice(ranges[i].begin,ranges[i].end+1); 
    } 
    return ranges; 
} 

工作例如:https://jsfiddle.net/shfpxp82/10/

+0

谢谢。有效。我遇到了一些与"s;有关的问题(如果我首先选择它们,它们会被视为字符),但是我会使用一些BBCode来替换它,它会像我一样满意地工作。 :D – user2374726

+0

好听。祝你好运! –

相关问题