link-by-relative-path.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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): void {
  11. const pagePath = this.pagePath;
  12. // Remember old renderer, if overridden, or proxy to default renderer
  13. const defaultRender = md.renderer.rules.link_open || function(tokens, idx, options, env, self) {
  14. return self.renderToken(tokens, idx, options);
  15. };
  16. md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
  17. if (tokens[idx] == null || (typeof tokens[idx].attrIndex !== 'function')) {
  18. return defaultRender(tokens, idx, options, env, self);
  19. }
  20. // get href
  21. const hrefIndex = tokens[idx].attrIndex('href');
  22. if (hrefIndex != null && hrefIndex >= 0) {
  23. const href: string = tokens[idx].attrs[hrefIndex][1];
  24. const currentPath: string | null = pagePath;
  25. // resolve relative path and replace
  26. if (PATTERN_RELATIVE_PATH.test(href) && currentPath != null) {
  27. const newHref = path.resolve(path.dirname(currentPath), href);
  28. tokens[idx].attrs[hrefIndex][1] = newHref;
  29. }
  30. }
  31. // pass token to default renderer.
  32. return defaultRender(tokens, idx, options, env, self);
  33. };
  34. }
  35. }