Skip to content

build: prevent markdown styling from bleeding into examples #31358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 14, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions tools/markdown-to-html/docs-marked-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import {basename, extname} from 'path';
/** Regular expression that matches example comments. */
const exampleCommentRegex = /<!--\s*example\(\s*([^)]+)\)\s*-->/g;

/** Marker inserted before the start of an example. */
const exampleStartMarker = '<!-- ___exampleStart___ -->';

/** Marker inserted after the end of an example. */
const exampleEndMarker = '<!-- ___exampleEnd___ -->';

/**
* Custom renderer for marked that will be used to transform markdown files to HTML
* files that can be used in the Angular Material docs.
Expand Down Expand Up @@ -78,19 +84,23 @@ export class DocsMarkdownRenderer extends Renderer {
*/
html(html: string) {
html = html.replace(exampleCommentRegex, (_match: string, content: string) => {
let replacement: string;

// using [\s\S]* because .* does not match line breaks
if (content.match(/\{[\s\S]*\}/g)) {
const {example, file, region} = JSON.parse(content.trim()) as {
example: string;
file: string;
region: string;
};
return `<div material-docs-example="${example}"
replacement = `<div material-docs-example="${example}"
${file ? `file="${file}"` : ''}
${region ? `region="${region}"` : ''}></div>`;
} else {
return `<div material-docs-example="${content}"></div>`;
replacement = `<div material-docs-example="${content}"></div>`;
}

return `${exampleStartMarker}${replacement}${exampleEndMarker}`;
});

return super.html(html);
Expand Down Expand Up @@ -120,6 +130,16 @@ export class DocsMarkdownRenderer extends Renderer {
this._slugger.seen = {};
this._referencedFragments.clear();

return `<div class="docs-markdown">${output}</div>`;
const markdownOpen = '<div class="docs-markdown">';

// The markdown styling can interfere with the example's styles, because we don't use
// encapsulation. We work around it by replacing the opening marker, left by the previous
// step, with a closing tag, and replacing the closing marker with an opening tag.
// The result is that we exclude the example code from the markdown styling.
output = output
.replace(new RegExp(exampleStartMarker, 'g'), '</div>')
.replace(new RegExp(exampleEndMarker, 'g'), markdownOpen);

return `${markdownOpen}${output}</div>`;
}
}
Loading