@diplodoc/transform
Version:
A simple transformer of text in YFM (Yandex Flavored Markdown) to HTML
94 lines (74 loc) • 3.01 kB
text/typescript
import MarkdownIt from 'markdown-it';
import {sep} from 'path';
import url from 'url';
import {PAGE_LINK_REGEXP, getHrefTokenAttr, isLocalUrl} from '../../utils';
import {getSinglePageAnchorId, resolveRelativePath} from '../../utilsFS';
import index from './index';
const replaceLinkHref = (input: string, href: string, newHref: string) => {
/* Try not replace include syntax */
return input.replace(`](${href})`, `](${newHref})`);
};
type Options = {
root: string;
path: string;
singlePage: boolean;
};
/* Replace the links to the markdown and yaml files if the singlePage option is passed in the options
* Example: replace [Text](../../path/to/file.md#anchor) with [Text](#_path_to_file_anchor)
* */
const collect = (input: string, options: Options) => {
const {root, path: startPath, singlePage} = options;
if (!singlePage) {
return;
}
let result = input;
/* Syntax "{% include [Text](_includes/file.md) %}" is parsed as link. Need to ignore errors */
const needSkipLinkFn = (href: string) => href.includes(`_includes${sep}`);
const transformLink = (href: string) => href;
const md = new MarkdownIt().use(index, {...options, transformLink, needSkipLinkFn});
const tokens = md.parse(result, {});
let i = 0;
while (i < tokens.length) {
if (tokens[i].type === 'inline') {
const childrenTokens = tokens[i].children || [];
let j = 0;
while (j < childrenTokens.length) {
const isLinkOpenToken = childrenTokens[j].type === 'link_open';
if (!isLinkOpenToken) {
j++;
continue;
}
const linkToken = childrenTokens[j];
const href = getHrefTokenAttr(linkToken);
const isIncludeLink = resolveRelativePath(startPath, href).includes(
`_includes${sep}`,
);
if (!href || !isLocalUrl(href) || isIncludeLink) {
j++;
continue;
}
const {pathname, hash} = url.parse(href);
if (pathname) {
const isPageFile = PAGE_LINK_REGEXP.test(pathname);
if (isPageFile) {
const newHref = getSinglePageAnchorId({
root,
currentPath: startPath,
pathname,
hash,
});
result = replaceLinkHref(result, href, newHref);
}
} else if (hash) {
const newHref = getSinglePageAnchorId({root, currentPath: startPath, hash});
result = replaceLinkHref(result, href, newHref);
}
j++;
}
}
i++;
}
// eslint-disable-next-line consistent-return
return result;
};
export = collect;