2

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 ?

1

1 Answer 1

4

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>

Sign up to request clarification or add additional context in comments.

14 Comments

let me check this .
Can you please elaborate a bit more
Actually, I have to show the user highlighted parts as well with the whole given string
And the class="mark" this classname will be diff each time
Its not like that I have to show a full document with the highlighted text and not the string which is only highlighted
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.