2019-11-08 03:40:20 +01:00
|
|
|
import { createElement, ReactElement } from "react";
|
|
|
|
import { DomElement } from 'html-react-parser';
|
|
|
|
|
2019-11-19 05:03:40 +01:00
|
|
|
const generateID = (title: string): string => {
|
|
|
|
return title
|
|
|
|
.replace('&', '-and-')
|
|
|
|
.replace('&', '-and-')
|
|
|
|
.replace(/[^A-Za-z0-9]/g, '-')
|
|
|
|
.replace(/-+/g, '-')
|
|
|
|
.replace(/^-/g, '')
|
|
|
|
.replace(/-$/g, '')
|
|
|
|
.toLowerCase();
|
|
|
|
}
|
2019-11-19 04:29:29 +01:00
|
|
|
/**
|
|
|
|
* If a header has a {#explicit-id}, add it as an attribute
|
|
|
|
* @param domNode
|
|
|
|
*/
|
2019-11-08 03:40:20 +01:00
|
|
|
const rewriteHeaders = (domNode: DomElement): ReactElement | false => {
|
|
|
|
if (!domNode.name) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
const firstChild = domNode.children ? domNode.children[0] : null;
|
|
|
|
if (firstChild && firstChild.type === 'text') {
|
|
|
|
const { data } = firstChild;
|
|
|
|
const matches = data.match(/^(.*?){#([A-Za-z0-9_-]+)\}$/);
|
2019-11-19 05:03:40 +01:00
|
|
|
let header;
|
|
|
|
let id;
|
2019-11-08 03:40:20 +01:00
|
|
|
if (matches) {
|
2019-11-19 05:03:40 +01:00
|
|
|
header = matches[1];
|
|
|
|
id = matches[2];
|
|
|
|
} else {
|
|
|
|
header = data;
|
|
|
|
id = generateID(data);
|
2019-11-08 03:40:20 +01:00
|
|
|
}
|
2019-11-19 05:03:40 +01:00
|
|
|
|
2020-01-16 22:26:52 +01:00
|
|
|
const anchor = createElement(
|
|
|
|
'a',
|
|
|
|
{
|
|
|
|
"aria-hidden": true,
|
|
|
|
className: 'anchor',
|
|
|
|
href: `#${id}`,
|
|
|
|
id,
|
|
|
|
key: id,
|
|
|
|
},
|
|
|
|
'#'
|
|
|
|
);
|
|
|
|
|
2019-11-19 05:03:40 +01:00
|
|
|
return createElement(
|
|
|
|
domNode.name,
|
2020-01-16 22:26:52 +01:00
|
|
|
{},
|
|
|
|
[ header, anchor ]
|
2019-11-19 05:03:40 +01:00
|
|
|
);
|
|
|
|
|
2019-11-08 03:40:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-11-19 05:03:40 +01:00
|
|
|
|
2019-11-08 03:40:20 +01:00
|
|
|
export default rewriteHeaders;
|