diff --git a/docs/Komponentengalerie/media-shortcuts.md b/docs/Komponentengalerie/media-shortcuts.md deleted file mode 100644 index a65e8334..00000000 --- a/docs/Komponentengalerie/media-shortcuts.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -page_id: d38be43d-eb1a-43f0-8b8b-42d9336fa726 ---- -import BrowserWindow from '@tdev-components/BrowserWindow'; - -# Medien Einfügen - -Folgende Quellen werden aktuell unterstützt: -- video -- audio -- youtube -- circuitverse -- learningapps - -```md -::video[./assets/yogi-bear.mp4]{width=100% height=200px} - -::audio[./assets/sound.mp3] -@by [KAM HESARI - Chill](https://freemusicarchive.org/music/kam-hesari/single/chill-3/) - -::youtube[https://www.youtube.com/embed/QPZ0pIK_wsc?si=fP8L8fYQ-TYgYwUe] - -::circuitverse[https://circuitverse.org/simulator/embed/rothe-inverter] - -::learningapps[https://learningapps.org/7863213] -``` - - -::video[./assets/yogi-bear.mp4]{width=100% height=200px} - - -::audio[./assets/sound.mp3] - -@by [KAM HESARI - Chill](https://freemusicarchive.org/music/kam-hesari/single/chill-3/) - - -::youtube[https://www.youtube.com/embed/QPZ0pIK_wsc?si=fP8L8fYQ-TYgYwUe] - - -::circuitverse[https://circuitverse.org/simulator/embed/rothe-inverter] - - -::learningapps[https://learningapps.org/7863213] - - - -## Installation - -:::info[Code] -- `src/plugins/remark-media` -::: - -:::info[`docusaurus.config.ts`] - -```ts -import mediaPlugin from './src/plugins/remark-media/plugin'; - -const REMARK_PLUGINS = [ - /* ... */ - mediaPlugin -]; -``` -::: diff --git a/docs/Komponentengalerie/remark-media/assets/sound.mp3 b/docs/Komponentengalerie/remark-media/assets/sound.mp3 new file mode 100644 index 00000000..d373631e Binary files /dev/null and b/docs/Komponentengalerie/remark-media/assets/sound.mp3 differ diff --git a/docs/Komponentengalerie/remark-media/assets/yogi-bear.mp4 b/docs/Komponentengalerie/remark-media/assets/yogi-bear.mp4 new file mode 100644 index 00000000..f1545e95 Binary files /dev/null and b/docs/Komponentengalerie/remark-media/assets/yogi-bear.mp4 differ diff --git a/docs/Komponentengalerie/remark-media/audio.mdx b/docs/Komponentengalerie/remark-media/audio.mdx new file mode 100644 index 00000000..a0a809a3 --- /dev/null +++ b/docs/Komponentengalerie/remark-media/audio.mdx @@ -0,0 +1,32 @@ +--- +page_id: 41c6a9c0-61fd-4c97-9375-936f552de079 +--- + +import BrowserWindow from '@tdev-components/BrowserWindow'; + +# ::audio + +Bindet eine lokale Audio-Datei ein. + +```mdx +::audio[./assets/sound.mp3] +@by [KAM HESARI - Chill](https://freemusicarchive.org/music/kam-hesari/single/chill-3/) +``` + + +::audio[./assets/sound.mp3] +@by [KAM HESARI - Chill](https://freemusicarchive.org/music/kam-hesari/single/chill-3/) + + +## Optionen + +css Eigenschaften +: Es können beliebige css-Eigenschaften in Form `eigenschaft=wert` angegeben werden, die auf das Video angewendet werden. + +```mdx +::audio[./assets/sound.mp3]{marginLeft=auto marginRight=auto display=block} +``` + + +::audio[./assets/sound.mp3]{marginLeft=auto marginRight=auto display=block} + diff --git a/docs/Komponentengalerie/remark-media/circuitverse.mdx b/docs/Komponentengalerie/remark-media/circuitverse.mdx new file mode 100644 index 00000000..336a9d15 --- /dev/null +++ b/docs/Komponentengalerie/remark-media/circuitverse.mdx @@ -0,0 +1,38 @@ +--- +page_id: 41c6a9c0-61fd-4c97-9375-936f552de079 +--- + +import BrowserWindow from '@tdev-components/BrowserWindow'; + +# ::circuitverse + +Bindet einen [Circuitverse](https://circuitverse.org/) Schaltkreis ein. + +```mdx +::circuitverse[https://circuitverse.org/simulator/embed/rothe-inverter] +``` + + +::circuitverse[https://circuitverse.org/simulator/embed/rothe-inverter] + + +## Optionen + +`height` +: Höhe des iframes. +: Standardmässig auf __315px__ gesetzt. +: z.B. `height=200px` +`width` +: Breite des iframes. +: Standardmässig auf __100%__ gesetzt. +css Eigenschaften +: Es können beliebige css-Eigenschaften in Form `eigenschaft=wert` angegeben werden, die auf das iframe angewendet werden. + + +```mdx +::circuitverse[https://circui...]{width=300px height=200px border="2px solid red"} +``` + + +::circuitverse[https://circuitverse.org/simulator/embed/rothe-inverter]{width=300px height=200px border="2px solid red"} + \ No newline at end of file diff --git a/docs/Komponentengalerie/remark-media/codepen.mdx b/docs/Komponentengalerie/remark-media/codepen.mdx new file mode 100644 index 00000000..9a437c20 --- /dev/null +++ b/docs/Komponentengalerie/remark-media/codepen.mdx @@ -0,0 +1,55 @@ +--- +page_id: 41c6a9c0-61fd-4c97-9375-936f552de079 +--- + +import BrowserWindow from '@tdev-components/BrowserWindow'; + +# ::codepen + +Bindet ein [Codepen](https://codepen.io/) ein. + +```mdx +::codepen[https://codepen.io/lebalz/pen/PwYoOBK] +``` + + +::codepen[https://codepen.io/lebalz/pen/PwYoOBK] + + +:::note[URL] +Es dürfen jeweils nur `codepen.io/user/embed/*` URLs verwendet werden, auf codepen.io wird allerdings die URL `codepen.io//pen/*` verwendet. Aus den __pen__ URLs wird automatisch die korrekte __embed__ URL generiert. +::: + +## Optionen + +`editable` +: Erlaubt das Bearbeiten des Codepens. +: Standardmässig `true`. +: z.B. `editable=false` +`theme` +: Wählt das Theme des Codepens. +: Standardmässig nicht gesetzt. +: z.B. `theme=dark` oder `theme=light` +`defaultTab` +: Wählt die Standard-Tabs des Codepens. +: Standardmässig `result`. +: z.B. `defaultTab=html,result` oder `defaultTab=css,js` +`height` +: Höhe des iframes. +: Standardmässig auf __500px__ gesetzt. +: z.B. `height=200px` +`width` +: Breite des iframes. +: Standardmässig auf __100%__ gesetzt. +: z.B. `width=200px` +css Eigenschaften +: Es können beliebige css-Eigenschaften in Form `eigenschaft=wert` angegeben werden, die auf das iframe angewendet werden. + + +```mdx +::codepen[https://codepen.io/lebalz/pen/PwYoOBK]{editable=false theme=light defaultTab=html,result height=300px} +``` + + +::codepen[https://codepen.io/lebalz/pen/PwYoOBK]{editable=false theme=light defaultTab=html,result height=300px} + diff --git a/docs/Komponentengalerie/remark-media/index.mdx b/docs/Komponentengalerie/remark-media/index.mdx new file mode 100644 index 00000000..9048c3e5 --- /dev/null +++ b/docs/Komponentengalerie/remark-media/index.mdx @@ -0,0 +1,32 @@ +--- +page_id: 117c8fba-9e80-4400-944d-050129aa9fe5 +--- +import DocCardList from '@theme/DocCardList'; + +# Remark Media + +Das Remark-Media Plugin hilft, iframes einfach einzubinden: + +```mdx +::[url]{optionen} +``` + + + +## Installation + +:::info[Code] +- `src/plugins/remark-media` +::: + +:::info[`docusaurus.config.ts`] + +```ts +import mediaPlugin from './src/plugins/remark-media/plugin'; + +const REMARK_PLUGINS = [ + /* ... */ + mediaPlugin, +]; +``` +::: \ No newline at end of file diff --git a/docs/Komponentengalerie/remark-media/learningapps.mdx b/docs/Komponentengalerie/remark-media/learningapps.mdx new file mode 100644 index 00000000..95cf660b --- /dev/null +++ b/docs/Komponentengalerie/remark-media/learningapps.mdx @@ -0,0 +1,37 @@ +--- +page_id: 41c6a9c0-61fd-4c97-9375-936f552de079 +--- + +import BrowserWindow from '@tdev-components/BrowserWindow'; + +# ::learningapps + +Bindet eine [Learning-App](https://learningapps.org/) ein. + +```mdx +::learningapps[https://learningapps.org/7863213] +``` + + +::learningapps[https://learningapps.org/7863213] + + +## Optionen +`height` +: Höhe des iframes. +: Standardmässig auf __500px__ gesetzt. +: z.B. `height=200px` +`width` +: Breite des iframes. +: Standardmässig auf __100%__ gesetzt. +: z.B. `width=200px` +css Eigenschaften +: Es können beliebige css-Eigenschaften in Form `eigenschaft=wert` angegeben werden, die auf das iframe angewendet werden. + +```mdx +::learningapps[https://learningapps.org/7863213]{width=300px height=200px border="2px solid red"} +``` + + +::learningapps[https://learningapps.org/7863213]{width=300px height=200px border="2px solid red"} + diff --git a/docs/Komponentengalerie/remark-media/video.mdx b/docs/Komponentengalerie/remark-media/video.mdx new file mode 100644 index 00000000..84c90133 --- /dev/null +++ b/docs/Komponentengalerie/remark-media/video.mdx @@ -0,0 +1,49 @@ +--- +page_id: 41c6a9c0-61fd-4c97-9375-936f552de079 +--- + +import BrowserWindow from '@tdev-components/BrowserWindow'; + +# ::video + +Fügt ein lokales Video ein. + +```mdx +::video[./assets/yogi-bear.mp4] +``` + + +::video[./assets/yogi-bear.mp4] + + +## Optionen +`autoplay` +: Startet das Video automatisch. +: Standardmässig `false`. +: z.B. `autoplay` +`muted` +: Schaltet den Ton des Videos stumm. +: Standardmässig `false`. +: z.B. `muted` +`loop` +: Startet das Video automatisch neu, wenn es beendet ist. +: Standardmässig `false`. +: z.B. `loop` +`height` +: Höhe des Videos. +: z.B. `height=200px` +`width` +: Breite des Videos. +: Standardmässig auf die natürliche Breite des Videos gesetzt (wobei `max-width=100%` gesetzt wird). +: z.B. `width=200px` +css Eigenschaften +: Es können beliebige css-Eigenschaften in Form `eigenschaft=wert` angegeben werden, die auf das Video angewendet werden. + + +```mdx +::video[./assets/yogi-bear.mp4]{width=300px height=200px muted autoplay loop border="2px solid red"} +``` + + +::video[./assets/yogi-bear.mp4]{width=300px height=200px muted autoplay loop border="2px solid red"} + diff --git a/docs/Komponentengalerie/remark-media/youtube.mdx b/docs/Komponentengalerie/remark-media/youtube.mdx new file mode 100644 index 00000000..b964a5b5 --- /dev/null +++ b/docs/Komponentengalerie/remark-media/youtube.mdx @@ -0,0 +1,35 @@ +--- +page_id: 9492f5bd-6e5d-403d-ad01-a9e1ba83d2e7 +--- +import BrowserWindow from '@tdev-components/BrowserWindow'; + +# ::youtube + +Fügt ein YouTube-Video ein. + +```mdx +::youtube[https://www.youtube.com/embed/QPZ0pIK_wsc?si=fP8L8fYQ-TYgYwUe] +``` + + +::youtube[https://www.youtube.com/embed/QPZ0pIK_wsc?si=fP8L8fYQ-TYgYwUe] + + +## Optionen + +`height` +: Höhe des Videos. +: Standardmässig nicht gesetzt, dann wird das __16 / 9__ Breitbildformat verwendet. +: z.B. `height=200px` +`width` +: Breite des Videos, wobei die `max-width` standardmässig auf `100%` gesetzt ist. +: z.B. `width=200px` + + +```mdx +::youtube[https://www.youtube...]{width=300px height=200px} +``` + + +::youtube[https://www.youtube.com/embed/QPZ0pIK_wsc?si=fP8L8fYQ-TYgYwUe]{height=200px width=300px} + \ No newline at end of file diff --git a/src/plugins/remark-media/plugin.ts b/src/plugins/remark-media/plugin.ts index 210e0272..d7487aec 100644 --- a/src/plugins/remark-media/plugin.ts +++ b/src/plugins/remark-media/plugin.ts @@ -9,7 +9,8 @@ enum LeafDirectiveName { AUDIO = 'audio', YOUTUBE = 'youtube', CIRCUITVERSE = 'circuitverse', - LEARNINGAPPS = 'learningapps' + LEARNINGAPPS = 'learningapps', + CODEPEN = 'codepen' } const DirectiveNames = Object.values(LeafDirectiveName) as string[]; @@ -73,13 +74,16 @@ const plugin: Plugin = function plugin(): Transformer { children: [], data: {} }); + if (Object.keys(style).length > 0) { + newNode.attributes.push(toJsxAttribute('style', style)); + } break; case LeafDirectiveName.YOUTUBE: const youtubeIframe: MdxJsxFlowElement = { type: 'mdxJsxFlowElement', name: 'iframe', attributes: [ - toJsxAttribute('width', '100%'), + toJsxAttribute('width', style.minWidth || '100%'), toJsxAttribute('height', style.height || '100%'), toJsxAttribute('src', src), toJsxAttribute('title', 'YouTube video player'), @@ -95,39 +99,88 @@ const plugin: Plugin = function plugin(): Transformer { }; newNode.name = 'div'; + const ytStyle: { marginLeft?: string; marginRight?: string; maxWidth?: string } = {}; + if (style.minWidth) { + ytStyle.marginLeft = 'auto'; + ytStyle.marginRight = 'auto'; + ytStyle.maxWidth = '100%'; + } newNode.attributes.push( toJsxAttribute('style', { - width: style.maxWidth || '100%', - aspectRatio: style.height ? undefined : '16 / 9' + ...ytStyle, + width: style.minWidth ? style.minWidth : '100%', + aspectRatio: style.height ? undefined : '16 / 9', + ...style }) ); newNode.children.push(youtubeIframe); break; case LeafDirectiveName.CIRCUITVERSE: newNode.name = 'iframe'; - newNode.attributes.push(toJsxAttribute('width', style.width || '100%')); newNode.attributes.push(toJsxAttribute('height', style.height || '315px')); newNode.attributes.push(toJsxAttribute('src', src)); newNode.attributes.push(toJsxAttribute('title', 'Circuit Verse')); newNode.attributes.push(toJsxAttribute('frameBorder', '0')); newNode.attributes.push(toJsxAttribute('scrolling', 'no')); - newNode.attributes.push(toJsxAttribute('webkitAllowFullScreen', '')); - newNode.attributes.push(toJsxAttribute('mozAllowFullScreen', '')); - newNode.attributes.push(toJsxAttribute('allowFullScreen', '')); + newNode.attributes.push(toJsxAttribute('allowFullScreen', true)); + newNode.attributes.push( + toJsxAttribute('style', { + width: style.minWidth ? style.minWidth : '100%', + maxWidth: '100%', + ...style + }) + ); break; case LeafDirectiveName.LEARNINGAPPS: const appId = new URL(src).pathname.split('/')[1]; const transformedSrc = `https://learningapps.org/watch?app=${appId}`; newNode.name = 'iframe'; - newNode.attributes.push(toJsxAttribute('width', style.width || '100%')); newNode.attributes.push(toJsxAttribute('height', style.height || '500px')); newNode.attributes.push(toJsxAttribute('src', transformedSrc)); newNode.attributes.push(toJsxAttribute('title', 'Learningapps')); newNode.attributes.push(toJsxAttribute('frameBorder', '0')); newNode.attributes.push(toJsxAttribute('scrolling', 'no')); - newNode.attributes.push(toJsxAttribute('webkitallowfullscreen', '')); - newNode.attributes.push(toJsxAttribute('mozAllowFullScreen', '')); - newNode.attributes.push(toJsxAttribute('allowFullScreen', '')); + newNode.attributes.push(toJsxAttribute('allowFullScreen', true)); + newNode.attributes.push( + toJsxAttribute('style', { + width: style.minWidth ? style.minWidth : '100%', + maxWidth: '100%', + ...style + }) + ); + break; + case LeafDirectiveName.CODEPEN: + let pen = src; + if (/codepen\.io\/.*\/pen\/.*/.test(src)) { + pen = src.replace(/\/pen\//, '/embed/'); + } + const penSource = new URL(pen); + penSource.searchParams.set('editable', 'true'); + if (attributes.theme) { + penSource.searchParams.set('theme-id', `${attributes.theme}`); + } + if (attributes.defaultTab) { + penSource.searchParams.set('default-tab', `${attributes.defaultTab}`); + } + if (attributes.editable !== undefined && !attributes.editable) { + penSource.searchParams.delete('editable'); + } + newNode.name = 'iframe'; + newNode.attributes.push(toJsxAttribute('height', style.height || '500px')); + newNode.attributes.push(toJsxAttribute('src', penSource.toString())); + newNode.attributes.push(toJsxAttribute('title', 'Codepen')); + newNode.attributes.push(toJsxAttribute('scrolling', 'no')); + newNode.attributes.push(toJsxAttribute('frameBorder', 'no')); + newNode.attributes.push(toJsxAttribute('loading', 'lazy')); + newNode.attributes.push(toJsxAttribute('allowTransparency', true)); + newNode.attributes.push(toJsxAttribute('allowFullScreen', true)); + newNode.attributes.push( + toJsxAttribute('style', { + width: style.minWidth ? style.minWidth : '100%', + maxWidth: '100%', + ...style + }) + ); break; } diff --git a/src/plugins/remark-media/tests/plugin.test.ts b/src/plugins/remark-media/tests/plugin.test.ts index ac8edb45..7405c497 100644 --- a/src/plugins/remark-media/tests/plugin.test.ts +++ b/src/plugins/remark-media/tests/plugin.test.ts @@ -73,13 +73,45 @@ describe('#medialinks', () => { " `); }); + it('can convert youtube directive with opitions', async () => { + const input = ` + ::youtube[https://www.youtube.com/embed/QPZ0pIK_wsc?si=fP8L8fYQ-TYgYwUe]{width=200px height=100px} + `; + const result = await process(input); + expect(result).toMatchInlineSnapshot(` + "
+