diff --git a/CHANGELOG.md b/CHANGELOG.md index cbff6540a..78af7f5c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - Images, videos, and other non-text content is now wider in View Mode - Notes may now be deleted directly from the history page - CodiMD instances can now be branded either with a '@ ' or '@ ' after the CodiMD logo and text +- Asciinema videos may now be embedded by pasting the URL of one video into a single line ### Changed diff --git a/src/components/editor/editor.tsx b/src/components/editor/editor.tsx index f5e9413cc..5cb1ba533 100644 --- a/src/components/editor/editor.tsx +++ b/src/components/editor/editor.tsx @@ -47,6 +47,9 @@ https://www.youtube.com/watch?v=KgMpKsp23yY ## Vimeo https://vimeo.com/23237102 +## Asciinema +https://asciinema.org/a/117928 + ## PDF {%pdf https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf %} diff --git a/src/components/editor/markdown-renderer/markdown-renderer.tsx b/src/components/editor/markdown-renderer/markdown-renderer.tsx index 149becc4b..57f5a02c0 100644 --- a/src/components/editor/markdown-renderer/markdown-renderer.tsx +++ b/src/components/editor/markdown-renderer/markdown-renderer.tsx @@ -26,6 +26,7 @@ import { highlightedCode } from './markdown-it-plugins/highlighted-code' import { linkifyExtra } from './markdown-it-plugins/linkify-extra' import { MarkdownItParserDebugger } from './markdown-it-plugins/parser-debugger' import './markdown-renderer.scss' +import { replaceAsciinemaLink } from './regex-plugins/replace-asciinema-link' import { replaceGistLink } from './regex-plugins/replace-gist-link' import { replaceLegacyGistShortCode } from './regex-plugins/replace-legacy-gist-short-code' import { replaceLegacySlideshareShortCode } from './regex-plugins/replace-legacy-slideshare-short-code' @@ -39,6 +40,7 @@ import { replaceQuoteExtraTime } from './regex-plugins/replace-quote-extra-time' import { replaceVimeoLink } from './regex-plugins/replace-vimeo-link' import { replaceYouTubeLink } from './regex-plugins/replace-youtube-link' import { ComponentReplacer, SubNodeConverter } from './replace-components/ComponentReplacer' +import { AsciinemaReplacer } from './replace-components/asciinema/asciinema-replacer' import { GistReplacer } from './replace-components/gist/gist-replacer' import { HighlightedCodeReplacer } from './replace-components/highlighted-fence/highlighted-fence-replacer' import { ImageReplacer } from './replace-components/image/image-replacer' @@ -99,6 +101,7 @@ export const MarkdownRenderer: React.FC = ({ content, cla md.use(markdownItRegex, replaceLegacySlideshareShortCode) md.use(markdownItRegex, replaceLegacySpeakerdeckShortCode) md.use(markdownItRegex, replacePdfShortCode) + md.use(markdownItRegex, replaceAsciinemaLink) md.use(markdownItRegex, replaceYouTubeLink) md.use(markdownItRegex, replaceVimeoLink) md.use(markdownItRegex, replaceGistLink) @@ -144,6 +147,7 @@ export const MarkdownRenderer: React.FC = ({ content, cla new GistReplacer(), new YoutubeReplacer(), new VimeoReplacer(), + new AsciinemaReplacer(), new PdfReplacer(), new ImageReplacer(), new TocReplacer(), diff --git a/src/components/editor/markdown-renderer/regex-plugins/replace-asciinema-link.ts b/src/components/editor/markdown-renderer/regex-plugins/replace-asciinema-link.ts new file mode 100644 index 000000000..e597ee46a --- /dev/null +++ b/src/components/editor/markdown-renderer/regex-plugins/replace-asciinema-link.ts @@ -0,0 +1,18 @@ +import { RegexOptions } from '../../../../external-types/markdown-it-regex/interface' + +const protocolRegex = /(?:http(?:s)?:\/\/)?/ +const domainRegex = /(?:asciinema\.org\/a\/)/ +const idRegex = /(\d+)/ +const tailRegex = /(?:[./?#].*)?/ +const gistUrlRegex = new RegExp(`(?:${protocolRegex.source}${domainRegex.source}${idRegex.source}${tailRegex.source})`) +const linkRegex = new RegExp(`^${gistUrlRegex.source}$`, 'i') + +export const replaceAsciinemaLink: RegexOptions = { + name: 'asciinema-link', + regex: linkRegex, + replace: (match) => { + // ESLint wants to collapse this tag, but then the tag won't be valid html anymore. + // noinspection CheckTagEmptyBody + return `` + } +} diff --git a/src/components/editor/markdown-renderer/replace-components/asciinema/asciinema-frame.tsx b/src/components/editor/markdown-renderer/replace-components/asciinema/asciinema-frame.tsx new file mode 100644 index 000000000..69d741558 --- /dev/null +++ b/src/components/editor/markdown-renderer/replace-components/asciinema/asciinema-frame.tsx @@ -0,0 +1,19 @@ +import React from 'react' +import { OneClickEmbedding } from '../one-click-frame/one-click-embedding' + +export interface AsciinemaFrameProps { + id: string +} + +export const AsciinemaFrame: React.FC = ({ id }) => { + return ( + +