Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Default Classes for each HTML element type #376

Closed
subodhpareek18 opened this issue Apr 12, 2017 · 5 comments
Closed

Feature Request: Default Classes for each HTML element type #376

subodhpareek18 opened this issue Apr 12, 2017 · 5 comments
Assignees
Labels
enhancement PR: request-changes This PR needs additional changes

Comments

@subodhpareek18
Copy link

subodhpareek18 commented Apr 12, 2017

I have read the documentation and gone through some of the issues, it seems like with some effort it might be possible to make an extension that does the required job. But I feel it really makes sense to have this functionality within the core library.

A lot of people use css ui kits like bootstrap, semantic-ui, etc. And if we could pass a bindings map object like so:

const classBindings = {
  h1: '.ui.large.header',
  h2: '.ui.medium.header',
  ul: '.ui.list'
  li: '.ui.item'
}

const converter = new showdown.Converter({ classBindings });

const text = `
# 1st Heading
## 2nd Heading

- first item
- second item
`
return  converter.makeHtml(text);
<h1 class="ui large header">1st Heading</h1>
<h2 class="ui medium header">2nd Heading</h2>
<ul class="ui list">
  <li class="ui item">first item</li>
  <li class="ui item">second item</li>
</ul>

Though if you think writing an extension for consuming this mappings object will be a very easy task, then could you please guide me on the same?

If possible I'd like to have the example added to the docs as well, like a recipe of sorts, so that other people can use it for bindings with any css ui kit of their choice.

And thanks so much for this wonderful library! 😁

@subodhpareek18
Copy link
Author

subodhpareek18 commented Apr 12, 2017

Actually it is very trivial to write such an extension. I can confirm that the one below does works as intended.

const showdown = require('showdown');

const classMap = {
  h1: 'ui large header',
  h2: 'ui medium header',
  ul: 'ui list',
  li: 'ui item'
}

const bindings = Object.keys(classMap)
  .map(key => ({
    type: 'output',
    regex: new RegExp(`<${key}>`, 'g'),
    replace: `<${key} class="${classMap[key]}">`
  }));

const conv = new showdown.Converter({
  extensions: [...bindings],
  noHeaderId: true // important to add this, else regex match doesn't work
});

const text = `
# 1st Heading
## 2nd Heading

- first item
- second item
`;

console.log(conv.makeHtml(text));
/**
​​​​​<h1 class="ui large header">1st Heading</h1>​​​​​
​​​​​<h2 class="ui medium header">2nd Heading</h2>​​​​​
​​​​​<ul class="ui list">​​​​​
​​​​​<li class="ui item">first item</li>​​​​​
​​​​​<li class="ui item">second item</li>​​​​​
​​​​​</ul>​​​​​
*/

You can close the issue, but as requested earlier, it would be useful for other people if this could be added to the documentation as a specific recipe.

@tivie tivie self-assigned this Apr 12, 2017
@tivie
Copy link
Member

tivie commented Apr 12, 2017

Thank you @zusamann

It is indeed a great idea to add this to the cookbook, which I will do as soon as possible.

@tivie tivie added PR: request-changes This PR needs additional changes enhancement and removed enhancement labels Aug 5, 2017
@tivie
Copy link
Member

tivie commented Aug 5, 2017

Added this to the wiki. https://github.com/showdownjs/showdown/wiki/Add-default-classes-for-each-HTML-element

Thank you very much for your contribution!!

@fabiospampinato
Copy link

fabiospampinato commented Dec 18, 2018

Actually it is very trivial to write such an extension.

Is it though? I suppose the proposed solution doesn't take into account code blocks, whose content shouldn't be modified at all.

@tivie
Copy link
Member

tivie commented Dec 19, 2018

I suppose the proposed solution doesn't take into account code blocks, whose content shouldn't be modified at all.

While this is technically true since, per the HTML spec, code tags allow any phrasing content, showdown always html-encodes html tags inside code blocks (as per markdown's own specification).

This means that:

some text

    this is some<b>code</b>
    <span>block</span>
    

will be literally converted into:

<p>some text</p>
<pre><code>
this is some&lt;b&gt;code&lt;/b&gt;
&lt;span&gt;block&lt;/span&gt;
</code></pre>

the only way you can have proper html tags inside code tags is when HTML is present in the source/input:

<pre><code>
this is some<b>code</b>
<span>block</span>
</code></pre>

While the last case is perfectly fine and valid, it's a rather odd edge case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement PR: request-changes This PR needs additional changes
Projects
None yet
Development

No branches or pull requests

3 participants