diff --git a/app/services/markdown_renderer.ts b/app/services/markdown_renderer.ts index bb8cff8..d0abf39 100644 --- a/app/services/markdown_renderer.ts +++ b/app/services/markdown_renderer.ts @@ -47,10 +47,37 @@ export class MarkdownRenderer { }) } + /** + * Rewrite markdown link tokens to include + * baseUrl when there isn't one. + */ + #rewrite(tokens: any[], baseUrl: string) { + for (const token of tokens) { + if (token.type === 'link_open') { + for (const attr of token.attrs) { + if (attr[0] === 'href') { + const value: string = attr[1] + try { + new URL(value) + } catch (_) { + attr[1] = new URL(value, `${baseUrl}/`).href + } + } + } + } + if (token.children !== null) { + this.#rewrite(token.children, baseUrl) + } + } + } + /** * Render the markdown to HTML */ - render(markdown: string): string { + render(markdown: string, baseUrl: string): string { + this.#renderer.core.ruler.push('baseurl', (state) => { + this.#rewrite(state.tokens, baseUrl) + }) const unsanitized = this.#renderer.render(markdown) return this.#sanitize(unsanitized) } diff --git a/app/services/packages_fetcher.ts b/app/services/packages_fetcher.ts index d6e94be..e158d4e 100644 --- a/app/services/packages_fetcher.ts +++ b/app/services/packages_fetcher.ts @@ -178,7 +178,7 @@ export class PackagesFetcher { return { package: this.#mergePackageStatsAndInfo(pkg, stats), - readme: this.#markdownRenderer.render(readme), + readme: this.#markdownRenderer.render(readme, pkg.github), } } }