mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 06:55:47 +01:00
add extension point for custom link protocol renderers in markdown (#1639)
This PR allows for custom link protocols to be declared and rendered in markdown.
A new extension point markdown-renderer.link.protocol allows for renderers to hook into the api and implement any custom protocol.
Example:
[description](myprotocol:somelink)
binder.bind("markdown-renderer.link.protocol", { protocol: "myprotocol", renderer: MyProtocolRenderer })
This renderer functions similar to link renderers and receives the href and the description. The latter as the children property.
This PR also fixes two bugs where external- and anchor links were not correctly rendered in pull requests by the review-plugin.
Co-authored-by: Eduard Heimbuch <eduard.heimbuch@cloudogu.com>
This commit is contained in:
committed by
GitHub
parent
8f91c217fc
commit
32b268e6f5
@@ -29,7 +29,7 @@ import sanitize from "rehype-sanitize";
|
||||
import remark2rehype from "remark-rehype";
|
||||
import rehype2react from "rehype-react";
|
||||
import gfm from "remark-gfm";
|
||||
import { binder } from "@scm-manager/ui-extensions";
|
||||
import { BinderContext } from "@scm-manager/ui-extensions";
|
||||
import ErrorBoundary from "../ErrorBoundary";
|
||||
import { create as createMarkdownHeadingRenderer } from "./MarkdownHeadingRenderer";
|
||||
import { create as createMarkdownLinkRenderer } from "./MarkdownLinkRenderer";
|
||||
@@ -46,6 +46,7 @@ import raw from "rehype-raw";
|
||||
import slug from "rehype-slug";
|
||||
import merge from "deepmerge";
|
||||
import { createComponentList } from "./createComponentList";
|
||||
import { ProtocolLinkRendererExtension, ProtocolLinkRendererExtensionMap } from "./markdownExtensions";
|
||||
|
||||
type Props = RouteComponentProps &
|
||||
WithTranslation & {
|
||||
@@ -94,6 +95,8 @@ const MarkdownErrorNotification: FC = () => {
|
||||
};
|
||||
|
||||
class MarkdownView extends React.Component<Props, State> {
|
||||
static contextType = BinderContext;
|
||||
|
||||
static defaultProps: Partial<Props> = {
|
||||
enableAnchorHeadings: false,
|
||||
skipHtml: false
|
||||
@@ -143,7 +146,7 @@ class MarkdownView extends React.Component<Props, State> {
|
||||
mdastPlugins = []
|
||||
} = this.props;
|
||||
|
||||
const rendererFactory = binder.getExtension("markdown-renderer-factory");
|
||||
const rendererFactory = this.context.getExtension("markdown-renderer-factory");
|
||||
let remarkRendererList = renderers;
|
||||
|
||||
if (rendererFactory) {
|
||||
@@ -158,8 +161,19 @@ class MarkdownView extends React.Component<Props, State> {
|
||||
remarkRendererList.heading = createMarkdownHeadingRenderer(permalink);
|
||||
}
|
||||
|
||||
if (basePath && !remarkRendererList.link) {
|
||||
remarkRendererList.link = createMarkdownLinkRenderer(basePath);
|
||||
let protocolLinkRendererExtensions: ProtocolLinkRendererExtensionMap = {};
|
||||
if (!remarkRendererList.link) {
|
||||
const extensionPoints = this.context.getExtensions(
|
||||
"markdown-renderer.link.protocol"
|
||||
) as ProtocolLinkRendererExtension[];
|
||||
protocolLinkRendererExtensions = extensionPoints.reduce<ProtocolLinkRendererExtensionMap>(
|
||||
(prev, { protocol, renderer }) => {
|
||||
prev[protocol] = renderer;
|
||||
return prev;
|
||||
},
|
||||
{}
|
||||
);
|
||||
remarkRendererList.link = createMarkdownLinkRenderer(basePath, protocolLinkRendererExtensions);
|
||||
}
|
||||
|
||||
if (!remarkRendererList.code) {
|
||||
@@ -188,7 +202,10 @@ class MarkdownView extends React.Component<Props, State> {
|
||||
attributes: {
|
||||
code: ["className"] // Allow className for code elements, this is necessary to extract the code language
|
||||
},
|
||||
clobberPrefix: "" // Do not prefix user-provided ids and class names
|
||||
clobberPrefix: "", // Do not prefix user-provided ids and class names,
|
||||
protocols: {
|
||||
href: Object.keys(protocolLinkRendererExtensions)
|
||||
}
|
||||
})
|
||||
)
|
||||
.use(rehype2react, {
|
||||
|
||||
Reference in New Issue
Block a user