Partially run code as html and as text Partially run code as html and as text jquery jquery

Partially run code as html and as text


There is an alternative syntax that uses square brackets instead of angle brackets.

Check if it solves your tag identifying problem without messing any other feature.

https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html

EDIT 1

To show the source code inside the <#code> tags when the HTML is parsed, you could escape it in your database (escape html special chars like <, > and & to < > and &). So, when it is rendered, no html tags will be created in the code content and the document won't be messed up.

Then, you can render all the content of the database directly as HTML: text will keep markup and code will be text.

To do that modification, you can use regular expressions to find what is enclosed by <#code> tags and replace with the HTML-escaped equivalent. The exact way to do it depends on the language you will be using for the job, as there are some differences in RegExes and in the available escape funcions.

EDIT 2

If you are loading the content using AJAX, you have the chance of applying the replace in javascript, AFTER the content was obtained from the server, keeping your database as it is.


Recap of the problem

For parsing HTML in javascript, you generally use a DOMParser object (supported by IE10+).

Like you said, parsing fails inside the data-type="code" section, because it does not know how to handle the </#...> tags...

const templ = `<section><div class="row"><div class="col-sm-12"><section data-type="code"><#code></#code></section></div></div><div class="row"><div class="col-sm-12" data-type="container-content"><section data-type="text"><u>Lorem</u> ipsum</section></div></div></section>`;const parser = new DOMParser();const doc = parser.parseFromString(templ, "text/html");console.log(  "Wrongly parsed </#code> tag:\n",  doc.querySelector("[data-type='code']").innerHTML);

Finding a way around

Now, it might sound like a good idea to try and do a quick regex find-and-replace on the characters that need to be escaped, but I wouldn't recommend it...

As far as I know, there's no way to "break in" to the parsing process or pass a strategy for certain types of elements...

I'd say this leaves you with two options. Either:

  1. Don't use the unparsable syntax inside the code section, as suggested by user Eduardo Poço in their answer

or, (my prefered direction), try to

  1. Modify the template itself to stop parsing the contents of the code sections all together

Using a modified template

There's a tag for "script" like content in HTML! It's, unsurprisingly, the <script> tag. Let's inject it in our code section:

<section data-type="code">    <script type="text">        <#code></#code>    </script></section>

The DOMParser won't touch this tag, leaving it exactly as is:

const templ = '<section><div class="row"><div class="col-sm-12"><section data-type="code"><script type="text"><#code></#code></' + 'script></section></div></div><div class="row"><div class="col-sm-12" data-type="container-content"><section data-type="text"><u>Lorem</u> ipsum</section></div></div></section>';const parser = new DOMParser();const doc = parser.parseFromString(templ, "text/html");console.log(  "Now, there's a <script> tag:\n",  doc.querySelector("[data-type='code']").innerHTML);

Note that I had to join the template string from two parts to make sure stackoverflow's snippet doesn't break. Are they experiencing a similar issue? :-o


Now, all we have to do is use the general DOM methods, including innerText (not innerHTML) to get the script's inner content back in to the visible part of the DOM:

var templ = '<section><div class="row"><div class="col-sm-12"><section data-type="code"><script type="text"><#code></#code></' + 'script></section></div></div><div class="row"><div class="col-sm-12" data-type="container-content"><section data-type="text"><u>Lorem</u> ipsum</section></div></div></section>`;'var parser = new DOMParser();var doc = parser.parseFromString(templ, "text/html");Array  .from(doc.querySelectorAll(    "[data-type='code'] > script")  )  .forEach(script => {      const codeTag = document.createElement("code");      codeTag.innerText = script.innerHTML;      script.replaceWith(codeTag);  });document.getElementById("wrapper").appendChild(doc.body.firstChild);
code { background: #efefef; }
<div id="wrapper"></div>


You could use charset codes, so it does not execute before outputting. HTML charset reference

They can edit it, since it appears normal and send it back to you or server. Make sure you include your charset reference in the head.

<meta charset="UTF-8"> // HTML5 <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"> // HTML4

<!-- @CHARSET / No execute -->&#60;section&#62;    &#60;div class="row"&#62;        &#60;div class="col-sm-12"&#62;            &#60;section data-type="code"&#62;                <#code> <!-- Run this --> </#code>            &#60;/section&#62;        &#60;/div&#62;    &#60;/div&#62;    &#60;div class="row"&#62;        &#60;div class="col-sm-12" data-type="container-content"&#62;            &#60;section data-type="text"&#62;                &#60;u&#62; <!-- Don't run --> &#60;/u&#62;             &#60;/section&#62;        &#60;/div&#62;    &#60;/div&#62;&#60;/section&#62;