React-markdown: Headings are missing anchors / ids

Created on 28 Mar 2017  路  6Comments  路  Source: remarkjs/react-markdown

# h1

parse =>

<h1>h1</h1>

not

<h1 id="h1">h1</h1>

image

Most helpful comment

This should be a core feature. I shouldn't have to go out of my way to implement something that is a core markdown feature.

All 6 comments

It's hard to know how to address these headers, so I've decided to leave it out of the core.
You can achieve the same functionality by using a Header renderer:

function flatten(text, child) {
  return typeof child === 'string'
    ? text + child
    : React.Children.toArray(child.props.children).reduce(flatten, text)
}

function HeadingRenderer(props) {
  var children = React.Children.toArray(props.children)
  var text = children.reduce(flatten, '')
  var slug = text.toLowerCase().replace(/\W/g, '-')
  return React.createElement('h' + props.level, {id: slug}, props.children)
}

<Markdown
  source="# Some heading!\n\nAnd a paragraph"
  renderers={{Heading: HeadingRenderer}}
/>

JSbin example here

In case it's useful for anyone in the future:

renderers={{Heading: HeadingRenderer}} now wants to be renderers={{heading: HeadingRenderer}}

(So lowercase renderer names.)

This should be a core feature. I shouldn't have to go out of my way to implement something that is a core markdown feature.

I had to lower-case heading with react-markdown 4.3.1

EDIT: Ah, was already commented @darraghbuckley, sorry...

How to get different IDs when you have same titles?

For exemple, I am using it to render markdown as a developers documentation, and one page can have multiple end points that are the same for example:

# route a
## GET - List
## POST - Create

# route b
## GET - List
## POST - Create

The solution proposed will generate same ids for the h2 generated and my Table of Contents will not work.

How to get different IDs when you have same titles?

For exemple, I am using it to render markdown as a developers documentation, and one page can have multiple end points that are the same for example:

# route a
## GET - List
## POST - Create

# route b
## GET - List
## POST - Create

The solution proposed will generate same ids for the h2 generated and my Table of Contents will not work.

I think you can simplify it. Just generate a unique id by yourself. Here is my example, hope can help you.

const generateId = (() => {
  let i = 0;
  return (prefix = '') => {
    i += 1;
    return `${prefix}-${i}`;
  };
})();

function HeadingRenderer(props: any) {
  const slug = `h${props.level}-${generateId('titile')}`;
  return createElement(`h${props.level}`, { id: slug }, props.children);
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  4Comments

LinusU picture LinusU  路  3Comments

wqh17101 picture wqh17101  路  3Comments

d0lb33 picture d0lb33  路  3Comments

neilyoung picture neilyoung  路  3Comments