link-by-relative-path.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import path from 'path';
  2. // https://regex101.com/r/vV8LUe/1
  3. const PATTERN_RELATIVE_PATH = new RegExp(/^(\.{1,2})(\/.*)?$/);
  4. export default class LinkerByRelativePathConfigurer {
  5. pagePath: string;
  6. constructor(pagePath: string) {
  7. this.pagePath = pagePath;
  8. }
  9. // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  10. configure(md, pagePath: string): void {
  11. // Remember old renderer, if overridden, or proxy to default renderer
  12. const defaultRender = md.renderer.rules.link_open || function(tokens, idx, options, env, self) {
  13. return self.renderToken(tokens, idx, options);
  14. };
  15. md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
  16. if (tokens[idx] == null || (typeof tokens[idx].attrIndex !== 'function')) {
  17. return defaultRender(tokens, idx, options, env, self);
  18. }
  19. // get href
  20. const hrefIndex = tokens[idx].attrIndex('href');
  21. if (hrefIndex != null && hrefIndex >= 0) {
  22. const href: string = tokens[idx].attrs[hrefIndex][1];
  23. const currentPath: string | null = pagePath;
  24. // resolve relative path and replace
  25. if (PATTERN_RELATIVE_PATH.test(href) && currentPath != null) {
  26. const newHref = path.resolve(path.dirname(currentPath), href);
  27. tokens[idx].attrs[hrefIndex][1] = newHref;
  28. }
  29. }
  30. // pass token to default renderer.
  31. return defaultRender(tokens, idx, options, env, self);
  32. };
  33. }
  34. }