mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-10-26 08:06:09 +01:00
add markdown codeblock renderer extension point (#1492)
Introduces a new extension point that allows developers to overwrite the default syntax highlighting renderer for specific code blocks defined in markdown. The extension point is dynamic and follows the pattern "markdown-renderer.code.{language}".
This feature lays the groundwork for the scm-markdown-plantuml-plugin.
This commit is contained in:
committed by
GitHub
parent
8eb599ff94
commit
831c8b0271
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
### Added
|
||||
- add markdown codeblock renderer extension point ([#1492](https://github.com/scm-manager/scm-manager/pull/1492))
|
||||
|
||||
## [2.12.0] - 2020-12-17
|
||||
### Added
|
||||
- Add repository import via dump file for Subversion ([#1471](https://github.com/scm-manager/scm-manager/pull/1471))
|
||||
|
||||
@@ -57,7 +57,10 @@ The following extension points are provided for the frontend:
|
||||
### roles.route
|
||||
### user.route
|
||||
### user.setting
|
||||
|
||||
### markdown-renderer.code.{language}
|
||||
- Dynamic extension point for custom language-specific renderers
|
||||
- Overrides the default Syntax Highlighter
|
||||
- Used by the Markdown Plantuml Plugin
|
||||
|
||||
# Deprecated
|
||||
|
||||
|
||||
54
scm-ui/ui-components/src/MarkdownCodeRenderer.tsx
Normal file
54
scm-ui/ui-components/src/MarkdownCodeRenderer.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import React, { FC } from "react";
|
||||
import SyntaxHighlighter from "./SyntaxHighlighter";
|
||||
import { ExtensionPoint, useBinder } from "@scm-manager/ui-extensions";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
type Props = {
|
||||
language?: string;
|
||||
value: string;
|
||||
indexLinks: { [key: string]: any };
|
||||
};
|
||||
|
||||
const MarkdownCodeRenderer: FC<Props> = (props) => {
|
||||
const binder = useBinder();
|
||||
const { language, indexLinks } = props;
|
||||
const extensionKey = `markdown-renderer.code.${language}`;
|
||||
if (binder.hasExtension(extensionKey, props)) {
|
||||
return <ExtensionPoint name={extensionKey} props={{ ...props, indexLinks }} />;
|
||||
}
|
||||
return <SyntaxHighlighter {...props} />;
|
||||
};
|
||||
|
||||
const mapStateToProps = (state: any) => {
|
||||
const indexLinks = state.indexResources.links;
|
||||
|
||||
return {
|
||||
indexLinks,
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(MarkdownCodeRenderer);
|
||||
@@ -21,7 +21,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import React from "react";
|
||||
import React, { FC } from "react";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import MarkdownView from "./MarkdownView";
|
||||
import styled from "styled-components";
|
||||
@@ -29,20 +29,22 @@ import styled from "styled-components";
|
||||
import TestPage from "./__resources__/test-page.md";
|
||||
import MarkdownWithoutLang from "./__resources__/markdown-without-lang.md";
|
||||
import MarkdownXmlCodeBlock from "./__resources__/markdown-xml-codeblock.md";
|
||||
import MarkdownUmlCodeBlock from "./__resources__/markdown-uml-codeblock.md";
|
||||
import MarkdownInlineXml from "./__resources__/markdown-inline-xml.md";
|
||||
import MarkdownLinks from "./__resources__/markdown-links.md";
|
||||
import MarkdownCommitLinks from "./__resources__/markdown-commit-link.md";
|
||||
import Title from "./layout/Title";
|
||||
import { Subtitle } from "./layout";
|
||||
import { MemoryRouter } from "react-router-dom";
|
||||
import { Binder, BinderContext } from "@scm-manager/ui-extensions";
|
||||
|
||||
const Spacing = styled.div`
|
||||
padding: 2em;
|
||||
`;
|
||||
|
||||
storiesOf("MarkdownView", module)
|
||||
.addDecorator(story => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||
.addDecorator(story => <Spacing>{story()}</Spacing>)
|
||||
.addDecorator((story) => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
||||
.addDecorator((story) => <Spacing>{story()}</Spacing>)
|
||||
.add("Default", () => <MarkdownView content={TestPage} skipHtml={false} />)
|
||||
.add("Code without Lang", () => <MarkdownView content={MarkdownWithoutLang} skipHtml={false} />)
|
||||
.add("Xml Code Block", () => <MarkdownView content={MarkdownXmlCodeBlock} />)
|
||||
@@ -54,4 +56,23 @@ storiesOf("MarkdownView", module)
|
||||
</>
|
||||
))
|
||||
.add("Links", () => <MarkdownView content={MarkdownLinks} basePath="/" />)
|
||||
.add("Commit Links", () => <MarkdownView content={MarkdownCommitLinks} />);
|
||||
.add("Commit Links", () => <MarkdownView content={MarkdownCommitLinks} />)
|
||||
.add("Custom code renderer", () => {
|
||||
const binder = new Binder("custom code renderer");
|
||||
const Container: FC<{ value: string }> = ({ value }) => {
|
||||
return (
|
||||
<div>
|
||||
<h4 style={{ border: "1px dashed lightgray", padding: "2px" }}>
|
||||
To render plantuml as images within markdown, please install the scm-markdown-plantuml-plguin
|
||||
</h4>
|
||||
<pre>{value}</pre>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
binder.bind("markdown-renderer.code.uml", Container);
|
||||
return (
|
||||
<BinderContext.Provider value={binder}>
|
||||
<MarkdownView content={MarkdownUmlCodeBlock} />
|
||||
</BinderContext.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -27,12 +27,12 @@ import { RouteComponentProps, withRouter } from "react-router-dom";
|
||||
import Markdown from "react-markdown/with-html";
|
||||
import { binder } from "@scm-manager/ui-extensions";
|
||||
import ErrorBoundary from "./ErrorBoundary";
|
||||
import SyntaxHighlighter from "./SyntaxHighlighter";
|
||||
import MarkdownHeadingRenderer from "./MarkdownHeadingRenderer";
|
||||
import { create } from "./MarkdownLinkRenderer";
|
||||
import { useTranslation, WithTranslation, withTranslation } from "react-i18next";
|
||||
import Notification from "./Notification";
|
||||
import { createTransformer } from "./remarkChangesetShortLinkParser";
|
||||
import MarkdownCodeRenderer from "./MarkdownCodeRenderer";
|
||||
|
||||
type Props = RouteComponentProps &
|
||||
WithTranslation & {
|
||||
@@ -81,13 +81,13 @@ const MarkdownErrorNotification: FC = () => {
|
||||
class MarkdownView extends React.Component<Props, State> {
|
||||
static defaultProps: Partial<Props> = {
|
||||
enableAnchorHeadings: false,
|
||||
skipHtml: false
|
||||
skipHtml: false,
|
||||
};
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
contentRef: null
|
||||
contentRef: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -137,12 +137,12 @@ class MarkdownView extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
if (!rendererList.code) {
|
||||
rendererList.code = SyntaxHighlighter;
|
||||
rendererList.code = MarkdownCodeRenderer;
|
||||
}
|
||||
|
||||
return (
|
||||
<ErrorBoundary fallback={MarkdownErrorNotification}>
|
||||
<div ref={el => this.setState({ contentRef: el })}>
|
||||
<div ref={(el) => this.setState({ contentRef: el })}>
|
||||
<Markdown
|
||||
className="content is-word-break"
|
||||
skipHtml={skipHtml}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
export default `# Uml Code Block in Markdown
|
||||
\`\`\`uml
|
||||
actor Foo1
|
||||
boundary Foo2
|
||||
control Foo3
|
||||
entity Foo4
|
||||
database Foo5
|
||||
collections Foo6
|
||||
Foo1 -> Foo2 : To boundary
|
||||
Foo1 -> Foo3 : To control
|
||||
Foo1 -> Foo4 : To entity
|
||||
Foo1 -> Foo5 : To database
|
||||
Foo1 -> Foo6 : To collections
|
||||
\`\`\``;
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user