Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overlapping of one string into another string highlighting issue

I have a string which can be like

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged

Now, In this I have an json which has the string start and end offset which I want to highlight. Now, logic I am using is like this --

$scope.highlightHTML = function(content, startoffset, endoffset) {
  var className = 'mark';
  console.log(content.substring(startoffset, endoffset));
  return content.replace(content.substring(startoffset, endoffset), '<span class="' + className + '">$&</span>');
}
//Only if you don't know if they are in the correct order:
jsonDataArray = jsonDataArray.sort((a, b) => a.startOffset - b.startOffset);

for (var i = jsonDataArray.length - 1; i >= 0; i--) {
  const item = jsonDataArray[i];
  responseData = $scope.highlightHTML(responseData, item.startOffset, item.endOffset, item.color);
};
$rootScope.data.htmlDocument = responseData.replace(/\n/g, "</br>");

So, Here I am trying to highlight from the last value of the array so that the offset will not be changed. Now, In this there is one problem and that is like the overlapping .Now,Lets say ,

In this text I have highlighted Lorem Ipsum has been by adding some span class . Now, for the next interation, if the startoffset and endoffset has a string which is nothing but Ipsum has been the industry's standard . Now, Here there will be overlapping of these two and then the highlighting is overlapping . So, I am not able get the exact text, because of that the offsets gets changed.

Now, Another solution which I applied was like -

var length = '<span class="mark"></span>'.length:
jsonDataArray.forEach(function(item, index) {
    responseData = $scope.highlightHTML(responseData, item.startOffset + (index * length), item.endOffset + (index * length), item.color);
});
$rootScope.data.htmlDocument = responseData.replace(/\n/g, "</br>");

But here also the same problem, like if some part of one thing is present in another then it creates some problems. Can any one please help me with this ?

like image 608
ganesh kaspate Avatar asked Apr 03 '18 03:04

ganesh kaspate


1 Answers

To avoid having keeping track of your indexes moving, I suggest you store the output string separately or in an array like I did below:

const str = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged';

const highlights = [{startOffset: 2, endOffset: 16}, {startOffset: 68, endOffset: 75}, {startOffset: 80, endOffset: 92}];

const result = [];
let currentIndex = 0;

highlights.forEach(h => {
  result.push(str.substring(currentIndex, h.startOffset));
  result.push(`<span class="mark">${str.substring(h.startOffset, h.endOffset)}</span>`);
  currentIndex = h.endOffset;
});

result.push(str.substring(currentIndex, str.length));

document.getElementById('root').innerHTML = result.join('');
.mark {
  color: red;
}
<div id="root"></div>
like image 90
klugjo Avatar answered Nov 08 '22 00:11

klugjo