@@ -13,12 +13,13 @@ function cleanAttribute(attribute: string | null): string {
1313 return attribute ? attribute . replace ( / ( \n + \s * ) + / g, '\n' ) : '' ;
1414}
1515
16- function resolveHref ( href : string , baseUrl : string ) : string {
17- if ( ! baseUrl ) return href ;
16+ function resolveHref ( href : string , pageUrl : string , baseUrl : string ) : string {
17+ if ( ! pageUrl ) return href ;
1818 try {
19- return new URL ( href , baseUrl ) . toString ( ) ;
19+ // Unlike a browser, keep in-page anchors on the page, even when a `<base>` points elsewhere.
20+ return new URL ( href , href . startsWith ( '#' ) ? pageUrl : baseUrl ) . toString ( ) ;
2021 } catch {
21- log . warning ( `Failed to resolve link against the page URL : ${ href } ` ) ;
22+ log . warning ( `Failed to resolve link: ${ href } ` ) ;
2223 return href ;
2324 }
2425}
@@ -28,31 +29,31 @@ function resolveHref(href: string, baseUrl: string): string {
2829 * links such as `/docs` remain valid once the markdown is used outside of the source page.
2930 * @see https://github.com/mixmark-io/turndown/blob/master/src/commonmark-rules.js
3031 */
31- const inlineLinkRule = ( baseUrl : string ) : Rule => ( {
32+ const inlineLinkRule = ( pageUrl : string , baseUrl : string ) : Rule => ( {
3233 filter : ( node , options ) => options . linkStyle === 'inlined'
3334 && node . nodeName === 'A'
3435 && Boolean ( node . getAttribute ( 'href' ) ) ,
3536 replacement : ( content , node ) => {
3637 const element = node as HTMLElement ;
37- const href = resolveHref ( element . getAttribute ( 'href' ) ! , baseUrl ) . replace ( / ( [ ( ) ] ) / g, '\\$1' ) ;
38+ const href = resolveHref ( element . getAttribute ( 'href' ) ! , pageUrl , baseUrl ) . replace ( / ( [ ( ) ] ) / g, '\\$1' ) ;
3839 const title = cleanAttribute ( element . getAttribute ( 'title' ) ) ;
3940 return `[${ content } ](${ href } ${ title ? ` "${ title . replace ( / " / g, '\\"' ) } "` : '' } )` ;
4041 } ,
4142} ) ;
4243
4344/**
4445 * Converts HTML to markdown using Turndown (source: Website Content Crawler).
45- * Relative links are resolved against `url `, when provided.
46+ * Relative links are resolved against `baseUrl`, and in-page anchors against `pageUrl `, when provided.
4647 */
47- export const htmlToMarkdown = ( html : string | null , url ?: string ) : string | null => {
48+ export const htmlToMarkdown = ( html : string | null , pageUrl ?: string , baseUrl = pageUrl ) : string | null => {
4849 try {
4950 if ( ! html ?. length ) return null ;
5051
5152 const processor = new TurndownService ( turndownSettings ) ;
5253 if ( html . length <= GFM_MAX_HTML_LENGTH ) {
5354 processor . use ( plugin . gfm ) ; // Use GitHub Flavored Markdown
5455 }
55- processor . addRule ( 'inlineLink' , inlineLinkRule ( url ?? '' ) ) ;
56+ processor . addRule ( 'inlineLink' , inlineLinkRule ( pageUrl ?? '' , baseUrl ?? '' ) ) ;
5657
5758 return processor . turndown ( html ) ;
5859 } catch ( err : unknown ) {
0 commit comments