I have a Gatsby + WP API blog setup (with Markdown enabled) and it's working great, except when I'm trying to display HTML markup as code snippets. I'm using escape characters (see below), but for some reason the HTML inside the <code>/<pre> tags is rendering as actual HTML instead of displaying as an HTML code snippet.
I understand that's what dangerouslySetInnerHTML is there to do, but I didn't think it would if I'm using the escape character <?
Here's the markup inside the WP blog post..
<pre class="language-markup"><code>
<div>
<p>Lorem ipsum...</p>
</div>
</code></pre>
And this is how I'm displaying the entire post content in the react component...
<section className="article-body" itemProp="articleBody"
dangerouslySetInnerHTML={{ __html: this.props.html }}
/>
The <div> and <p> tags rendering as HTML, instead of displayed as a code snippet..
Is there some other way I should be doing this? For the record I also tried this using a 'non-dangerously' method (react-render-html) with the same results.
-- UPDATE: --
I was able to display the HTML as a code snippet by replacing the <code> tag with <xmp>. I know this tag is no longer officially supported, and it's far from elegant, so I think I may try to separate code snippets from the rest of the content as suggested below.
I tried it in CodeSandbox, too - working as expected. If you're sure about data (escaping) received from WP API I affraid it's a Gatsby issue. There must be a place where it's modified (unescaped).
If data will be ok and you don't want to make deep ivestigation there could be workaround. Split article body and treat sections separately - texts and code snippets. The second wrap with code literal with sth like this:
const CodeBlock = (props) => {
return <section className="article-code">
<pre className="language"><code>{`${props.html}`}</code></pre>
</section>
}
Of course remove unused first and last line of original code/snippet block.
Related
it's simple html tag related problem, I guess.
I want to share few lines of code in my blog, and I want to write <h1> heading</h1>. visitors must see <h1> heading </h1>, and not just heading. do I need to use JavaScript for this, please help me with this problem.
you can use HTML Entities like < , >
<h1><h1>heading;/h1></h1>
and this link may help you https://www.w3schools.com/html/html_entities.asp
There are two ways of doing this:
Escape the Characters using HTML Entities or Using a JS Library
Dynamically add the content using JavaScript textContent Property.
Here is a Sample code using both:
const codeSnippet = document.getElementById("codeSnippet");
codeSnippet.textContent = "<h1>Heading</h1>";
<div>
<p>Escaping:</p>
<code>
<h1>Heading</h1>
</code>
</div>
<div>
<p>Dynamically added usisng JS:</p>
<code id="codeSnippet"></code>
</div>
I am using MarkEd which implements GitHub flavoured markdown.
I have some working markdown:
## Test heading
a paragraph.
## second heading
another paragraph
Which creates:
<h2 id="test-heading">Test heading</h2>
<p>a paragraph.</p>
<h2 id="second-heading">second heading</h2>
<p>another paragraph</p>
I would like to wrap that markdown section in a div, eg:
<div class="blog-post">
## Test heading
a paragraph.
## second heading
another paragraph
</div>
However this returns the following HTML:
<div class="blog-post">
## Test heading
a paragraph.
## second heading
another paragraph
</div>
Eg, no markdown, literally '## Test heading' appears in the HTML.
How can I properly wrap my markdown in a div?
I have found the following workaround, however it is ugly and not an actual fix:
<div class="blog-post">
<div></div>
## Test heading
a paragraph.
## second heading
another paragraph
</div>
Markdown
For Markdown, This is by design. From the Inline HTML section of the Markdown reference:
Note that Markdown formatting syntax is not processed within block-level HTML tags. E.g., you can’t use Markdown-style emphasis inside an HTML block.
But it is explicitly allowed for span-level tags:
Unlike block-level HTML tags, Markdown syntax is processed within span-level tags.
So, depending on your use-case, you might get away with using a span instead of a div.
CommonMark
If the library you use implements CommonMark, you are lucky. Example 108 and 109 of the spec show that if you keep an empty line in between the HTML block and the markdown code, the contents will be parsed as Markdown:
<div>
*Emphasized* text.
</div>
should work, while the following shouldn't:
<div>
*Emphasized* text.
</div>
And, again according to the same section in the reference, some implementations recognize an additional markdown=1 attribute on the HTML tag to enable parsing of Markdown inside it.
Though it doesn't seem to work in StackOverflow yet:
Testing **Markdown** inside a red-background div.
GitHub Pages supports the markdown="1" attribute to parse markdown inside HTML elements, e.g.
<div class="tip" markdown="1">Have **fun!**</div>
Note: As of 2019/03, this doesn't work on github.com, only GitHub Pages.
Note: Quotes, as in markdown="1", are not required by HTML5 but if you don't use quotes (markdown=1), GitHub does not recognize it as HTML. Also, support is buggy right now. You will likely get incorrect output if your HTML element is larger than a single paragraph. For example, due to bugs I was unable to embed a Markdown list inside a div.
If you find yourself in an environment in which markdown="1" doesn't work but span does, another option is to use <span style="display:block"> so that block-level classes are compatible with it, e.g.
<span style="display:block" class="note">It **works!**</span>
Tip: <span class="note"></span> is shorter than <div class="note" markdown="1"></div>, so if you control the CSS you might prefer to use <span> and add display: block; to your CSS.
Markdown Extra is needed to be able to for Markdown formatting works inside an HTML blocks, please check the documentation stated here -> https://michelf.ca/projects/php-markdown/extra/
Markdown Extra gives you a way to put Markdown-formatted text inside
any block-level tag. You do this by adding a markdown attribute to the
tag with the value 1 — which gives markdown="1"
Last resort option:
Some libraries may be case sensitive.
Try <DIV> instead of <div> and see what happens.
Markdownsharp has this characteristic - although on StackOverflow they strip out all DIVs anyway so don't expect it to work here.
By looking at the docs for Extending Marked and modifying the html renderer method, you can do something like this to replace the parts between tags with parsed markdown. I haven't done extensive testing, but it worked with my first few attempts.
const marked = require('marked');
const renderer = new marked.Renderer();
renderer.html = (mixedContent) => mixedContent.replace(/[^<>]+?(?=<)/g, (match) => {
const tokens = marked.lexer(match);
return marked.parser(tokens);
});
Edit
this new regex will ensure that only markdown with lines between it and the html tags will be parsed.
const marked = require('marked');
const renderer = new marked.Renderer();
renderer.html = (mixedContent) => mixedContent.replace(/\n\n[^<>]+?\n\n(?=<)/g, (match) => {
const tokens = marked.lexer(match);
return marked.parser(tokens);
});
In my case (on GitHub), the problem was resolved when I added newline between html tags and markdown text.
I am making a forum with markdown support.
I've been using meteor's markdown parser {{#markdown}} and have found something disturbing that I can't seem to figure out.
I am using {{#markdown}}{{content}}{{/markdown}} to render the content inserted into database.
The disturbing thing, for example, if someone writes up html without inserting it into the code block in the content...
example
<div class = "col-md-12">
Content Here
</div>
This will render as a column. They could also make buttons and etc through writing the HTML for it.
How to disable this behaviour so that when HTML is written it will not render into HTML but just simply show it as text?
You can write global helper, which will strip all html tags:
function stripHTML(string){
s = string.replace(/(<([^>]+)>)/ig, '');
return s;
}
Template.registerHelper('stripHTML', stripHTML)
Usage :
{{#markdown}}{{stripHTML content}}{{/markdown}}
Test it in console:
stripHTML("<div>Inside dive</div> Text outside")
I am using MarkEd which implements GitHub flavoured markdown.
I have some working markdown:
## Test heading
a paragraph.
## second heading
another paragraph
Which creates:
<h2 id="test-heading">Test heading</h2>
<p>a paragraph.</p>
<h2 id="second-heading">second heading</h2>
<p>another paragraph</p>
I would like to wrap that markdown section in a div, eg:
<div class="blog-post">
## Test heading
a paragraph.
## second heading
another paragraph
</div>
However this returns the following HTML:
<div class="blog-post">
## Test heading
a paragraph.
## second heading
another paragraph
</div>
Eg, no markdown, literally '## Test heading' appears in the HTML.
How can I properly wrap my markdown in a div?
I have found the following workaround, however it is ugly and not an actual fix:
<div class="blog-post">
<div></div>
## Test heading
a paragraph.
## second heading
another paragraph
</div>
Markdown
For Markdown, This is by design. From the Inline HTML section of the Markdown reference:
Note that Markdown formatting syntax is not processed within block-level HTML tags. E.g., you can’t use Markdown-style emphasis inside an HTML block.
But it is explicitly allowed for span-level tags:
Unlike block-level HTML tags, Markdown syntax is processed within span-level tags.
So, depending on your use-case, you might get away with using a span instead of a div.
CommonMark
If the library you use implements CommonMark, you are lucky. Example 108 and 109 of the spec show that if you keep an empty line in between the HTML block and the markdown code, the contents will be parsed as Markdown:
<div>
*Emphasized* text.
</div>
should work, while the following shouldn't:
<div>
*Emphasized* text.
</div>
And, again according to the same section in the reference, some implementations recognize an additional markdown=1 attribute on the HTML tag to enable parsing of Markdown inside it.
Though it doesn't seem to work in StackOverflow yet:
Testing **Markdown** inside a red-background div.
GitHub Pages supports the markdown="1" attribute to parse markdown inside HTML elements, e.g.
<div class="tip" markdown="1">Have **fun!**</div>
Note: As of 2019/03, this doesn't work on github.com, only GitHub Pages.
Note: Quotes, as in markdown="1", are not required by HTML5 but if you don't use quotes (markdown=1), GitHub does not recognize it as HTML. Also, support is buggy right now. You will likely get incorrect output if your HTML element is larger than a single paragraph. For example, due to bugs I was unable to embed a Markdown list inside a div.
If you find yourself in an environment in which markdown="1" doesn't work but span does, another option is to use <span style="display:block"> so that block-level classes are compatible with it, e.g.
<span style="display:block" class="note">It **works!**</span>
Tip: <span class="note"></span> is shorter than <div class="note" markdown="1"></div>, so if you control the CSS you might prefer to use <span> and add display: block; to your CSS.
Markdown Extra is needed to be able to for Markdown formatting works inside an HTML blocks, please check the documentation stated here -> https://michelf.ca/projects/php-markdown/extra/
Markdown Extra gives you a way to put Markdown-formatted text inside
any block-level tag. You do this by adding a markdown attribute to the
tag with the value 1 — which gives markdown="1"
Last resort option:
Some libraries may be case sensitive.
Try <DIV> instead of <div> and see what happens.
Markdownsharp has this characteristic - although on StackOverflow they strip out all DIVs anyway so don't expect it to work here.
By looking at the docs for Extending Marked and modifying the html renderer method, you can do something like this to replace the parts between tags with parsed markdown. I haven't done extensive testing, but it worked with my first few attempts.
const marked = require('marked');
const renderer = new marked.Renderer();
renderer.html = (mixedContent) => mixedContent.replace(/[^<>]+?(?=<)/g, (match) => {
const tokens = marked.lexer(match);
return marked.parser(tokens);
});
Edit
this new regex will ensure that only markdown with lines between it and the html tags will be parsed.
const marked = require('marked');
const renderer = new marked.Renderer();
renderer.html = (mixedContent) => mixedContent.replace(/\n\n[^<>]+?\n\n(?=<)/g, (match) => {
const tokens = marked.lexer(match);
return marked.parser(tokens);
});
In my case (on GitHub), the problem was resolved when I added newline between html tags and markdown text.
I am having a hard time figuring out how to do this...
I am essentially saving a huge blog post in a property called "Body" in a class called "Post". In body I will have various things like
<p> Hello world </p>
<p> Some random paragraph </p>
<codeblock> Here is an example of a basic HTML page
<html>
<body>
<h1> Hello Guys ! </h1>
</body>
</html>
</codeblock>
Then I want to have a code block and thus I want the HTML/CSS/Javascript/etc to just be parsed to the page as HTML encoded/decoded so I literally want the tags and angle brackets to show up on the page instead of being parsed as whatever they are.
I also have a HTML tag called which is ended by . It's nothing special it just indents and adds some specific CSS with it. I want the markup before the and after the tag to render the HTML tags as necessary.
Currently I am literally outputting the contents of the Body property using
#Html.Raw(post.Body)
Nothing special when I save it to the DB:
#Html.TextAreaFor(model => model.Body)
So for those that are still having this issue, this is how I resolved it.
1) I included prettyprint. See link below
https://google-code-prettify.googlecode.com/svn/trunk/README.html
2) When editing a post I just add the following code
//Bunch of code
Example:
var http = require("http");
var server = http.createServer(function(req, res){
console.log(req.url);
resp.write("<html><body>" + req.url + "</html></body>");
resp.end();
});
server.listen(3000);
</pre>
In my Razor View I have the following code:
<div class="blog margin-bottom-40" onload="prettyPrint()">
//Bunch of other code up here for my view
<div class="blogpost">
#Html.Raw(post.Body)
</div>
</div>
My blog is www.techiejs.com
Feel free to have a look and if you need another file from my solution let me know. Currently my git repository is private.