3

I have the following code with a textarea covering the left half side and a div covering the right half side. Whatever is inserted on the left gets copied to the right with the HTML tags (<...>) colored in brown.

The issue I have is how to make it so that if the tag is inside quotation marks or apostrophes (turning it into a string instead) it doesn't get captured by the RegEx pattern in the replace method (doesn't turn brown).

To explain it better, put the following text inside the code snippet's textarea:

<html>
  <head>
    <script>
      function getString() {
        return "This string's content contains a tag \"<>\" which isn't suppost to be captured by the RegEx pattern in the replace method";
      }
    </script>
  </head>
</html>

function HtmlEncode(s) {
  let el = document.createElement("div");
  el.innerText = el.textContent = s;
  s = el.innerHTML;
  return s;
}
function textarea_oninput() {
  let text = document.getElementsByTagName('textarea')[0].value;
  text = HtmlEncode(text);
  document.getElementsByTagName('div')[0].innerHTML = text.replace(/&lt;(.*?(?=(?:&gt;)))&gt;/g, "<span style=\"color: rgb(155, 112, 63)\">&lt;$1&gt;</span>");
}
body {
  margin: 0px;
}
textarea {
  background: rgb(20, 20, 20);
  border-color: red;
  color: lightGray;
  height: 100%;
  margin: 0px;
  outline: 0;
  position: fixed;
  resize: none;
  white-space: nowrap;
  width: calc(50% - 0px);
}
div {
  background: rgb(20, 20, 20);
  border: 1px solid green;
  color: lightGray;
  font-family: monospace;
  height: calc(100% - 4px);
  left: 50%;
  margin: 0px;
  outline: 0;
  overflow: auto;
  padding: 2px 0px 0px 2px;
  position: fixed;
  resize: none;
  white-space: pre;
  width: calc(50% - 4px);
}
<textarea oninput="textarea_oninput()" spellcheck="false"></textarea>
<div></div>

Making the RegEx pattern something like /"|'.+tag.+"|'/ isn't enough because there's \", \', ' inside a string with ", " inside a string with ' and possibly more that I'm missing to take into account.

2
  • input and output example? I put this one <a>aasdas</a> "<b>aasds</b>" and the "b" example is in brown Commented Dec 13, 2017 at 12:30
  • Input: <script>var str1 = " ' < \" ' > ' \' "; var str2 = ' " < \" ' > ' \' ';</script>. Output is only the script tags being colored. Commented Dec 13, 2017 at 12:33

1 Answer 1

1

You have to match literal strings earlier than HTML tags:

document.getElementsByTagName('div')[0].innerHTML = text.replace(/"[^"\\]*(?:\\.[^\\"]*)*"|'[^'\\]*(?:\\.[^\\']*)*'|&lt;((?:.(?!&lt;))*)&gt;/g, function(match, p1) {
    return p1 ? "<span style=\"color: rgb(155, 112, 63)\">&lt;" + p1 + "&gt;</span>" : match;
});

Note: catastrophic backtracking is probable.

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

6 Comments

That's as confusing as I expected (seeing the result without making it myself bit by bit) but it seems to work as intended so thank you. I will try to learn it.
Added a ? in the 3th alternative &lt;((?:.(?!&lt;))*?)&gt; to make the * quantifier non-greedy and changed the return condition to p1 !== undefined so it distinguishes when the argument p1 is passed or when it's empty "", coloring <>.
Why did you made quantifier non-greedy?
<<>> gets fully colored if greedy and only <<> if non-greedy which is how the notepad++ works (which is where I'm copying the syntax highlighting from).
In your question you talked about HTML tags. What does <<>> have to do with HTML tags?
|

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.