1

I have a string myString="<pre class='ql-syntax'><code><html><body>Will this work?</body></html></code></pre>" which needs to be rendered in a webpage such that the content inside the <code> block is encoded so it shows up as is.

$('<div/>').html(htmlString).html() removes the html and body tags and outputs the following:

<pre class="ql-syntax"><code>Will this work?</code></pre>

What I want the output to be is:

<pre class="ql-syntax"><code>&lt;html&gt;hello&lt;/html&gt;</code></pre>

so on the webpage, the entire content which is inside the code block renders.

How do I encode only the part of the myString which is between the <code> block?

I am fetching the myString from the database, so I don't have any control over how I construct the myString. I can manipulate it however I want to make sure the html inside the code block renders as is.

maheshmurthy
  • 155
  • 1
  • 9

3 Answers3

2

I suggest you want only

 <code><html><body>Will this work?</body></html></code>

to be put to a pre. It's better you make a pre placeholder. Than just find it and set innerHtml. For example something like this:

<pre class="ql-syntax" id="code"></pre>

var pre = document.getElementById("code");
var codeLength = '<code>'.length;
var start = htmlString.indexOf('<code>');
var stop = htmlString.indexOf('</code>');
if (start != -1 && stop != -1 && stop > start)
    pre.innerHtml = htmlString.substring(start+codeLength, stop-start-codeLength);
norekhov
  • 3,915
  • 25
  • 45
0

If I understand your question, you need to HTML-encode the string within and including the <code> tags. See HTML-encoding lost when attribute read from input field

I'm not sure how you're constructing the string in the first place, but the code in the linked post should get you started. Perhaps something like this:

var newstring = "<pre class="ql-syntax">" + htmlEncode("<code><html><body>Will this work?</body></html></code>") + "</pre>";

Does this help?

Community
  • 1
  • 1
Sandy Gettings
  • 693
  • 5
  • 21
  • Yeah, pretty much. But how do I parse and split the string to extract everything between code block and call htmlEncode on just that part? – maheshmurthy Apr 23 '17 at 22:34
  • Well, given an arbitrary string, there are any number of ways to split it into parts, depending on the language and techniques you prefer. For example, regular expressions are elegant but may be difficult to learn. Or in C#, for example, you can find the position of the "" and "" tags with string.IndexOf() method. In any case, you'll probably want to parse the original string into its three substrings, and then concatenate them back together with the middle substring HTML-encoded. If you don't already know how to use these techniques, it would be a great learning exercise. – Sandy Gettings Apr 24 '17 at 23:25
0

You can use String.prototype.match() with RegExp /(<pre?\s.+?>)|(<code>)|[^\1].+(?=<\/code>)/g to match "<pre" followed by space character followed by one or more characters followed by ">" or "<code>" or not previous capture group "<code>" followed by one or more characters followed by "</code>".

Create <div> element and append to document.body, call .shift() on array returned by .match() to get "<pre>", set div .innerHTML to result of .shift(); call .shift() to get "<code>" match, set as .innerHTML of div.firstChild : <pre>, call .shift(), set result as .textContent of div.firstChild.firstChild : <code>.

var str = `<pre class="ql-syntax"><code><html><body>Will this work?</body></html></code></pre>`;
var matches = str.match(/(<pre?\s.+?>)|(<code>)|[^\1].+(?=<\/code>)/g);
var div = document.createElement("div");
document.body.appendChild(div);
var pre = matches.shift();
div.innerHTML = pre;
var code = matches.shift();
div.firstChild.innerHTML = code;
var html = matches.shift();
div.firstChild.firstChild.textContent = html;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
guest271314
  • 1
  • 15
  • 104
  • 177