Skip to content

Commit

Permalink
feat(bi-directional-links): support audios and videos type of bd links
Browse files Browse the repository at this point in the history
Signed-off-by: Neko Ayaka <[email protected]>
  • Loading branch information
nekomeowww committed Jul 13, 2024
1 parent 5cf85aa commit e49ec42
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 3 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ Images are supported:

![[foxtail field.jpg]]

Audio is not a concern either:

![[Applause.mp3]]

Video is even less of a problem:

![[Big rabbit came out of the hutch.mp4]]

## Installation

It is easy and straightforward to install the Bi-directional links plugin into your VitePress project, please follow the steps under [Getting started](./getting-started) page!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,26 @@ Demo

![[pages/en/integrations/markdown-it-bi-directional-links/images/same-name/railway near by beach same name.jpg]]

#### Audio with absolute path

```markdown
![[pages/en/integrations/markdown-it-bi-directional-links/audios/Applause.mp3]]
```

Demo

![[pages/en/integrations/markdown-it-bi-directional-links/audios/Applause.mp3]]

#### Video with absolute path

```markdown
![[pages/en/integrations/markdown-it-bi-directional-links/videos/Big rabbit came out of the hutch.mp4]]
```

Demo

![[pages/en/integrations/markdown-it-bi-directional-links/videos/Big rabbit came out of the hutch.mp4]]

#### Absolute path with custom text

```markdown
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ Obsidian 同名页面:[[pages/zh-CN/integrations/markdown-it-bi-directional-li

![[一片 狗尾草.jpg]]

音频也不在话下:

![[鼓掌声.mp3]]

视频更是没有问题:

![[大兔子从兔窝中钻出.mp4]]

## 安装

安装是非常简单容易的,请移步至[快速上手](./getting-started)阅读试试看吧!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,26 @@ document.querySelector('#为什么')

![[pages/zh-CN/integrations/markdown-it-bi-directional-links/images/same-name/海滩铁轨 同名图片.jpg]]

#### 音频配合绝对路径

```markdown
![[pages/zh-CN/integrations/markdown-it-bi-directional-links/audios/鼓掌声.mp3]]
```

效果

![[pages/zh-CN/integrations/markdown-it-bi-directional-links/audios/鼓掌声.mp3]]

#### 视频配合绝对路径

```markdown
![[pages/zh-CN/integrations/markdown-it-bi-directional-links/videos/大兔子从兔窝中钻出.mp4]]
```

效果

![[pages/zh-CN/integrations/markdown-it-bi-directional-links/videos/大兔子从兔窝中钻出.mp4]]

#### 绝对路径和自定义文案

```markdown
Expand Down
Binary file not shown.
32 changes: 32 additions & 0 deletions packages/markdown-it-bi-directional-links/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,38 @@ describe('markdown-it-bi-directional-links', () => {
expect(rendered).toBe('<p><img src="/foo.png" alt=""></p>\n')
})

it('should render simple form for audio', () => {
const rendered = new MarkdownIt({ html: true })
.use(BiDirectionalLinks({ dir: testdataDir }))
.render('![[foo.mp3]]')

expect(rendered).toBe('<p><audio controls="true" preload="metadata"><source src="/foo.mp3"></audio></p>\n')
})

it('should render simple form for audio without attachment markup', () => {
const rendered = new MarkdownIt({ html: true })
.use(BiDirectionalLinks({ dir: testdataDir }))
.render('[[foo.mp3]]')

expect(rendered).toBe('<p><audio controls="true" preload="metadata"><source src="/foo.mp3"></audio></p>\n')
})

it('should render simple form for videos', () => {
const rendered = new MarkdownIt({ html: true })
.use(BiDirectionalLinks({ dir: testdataDir }))
.render('![[foo.mp4]]')

expect(rendered).toBe('<p><video controls="true" preload="metadata"><source src="/foo.mp4"></video></p>\n')
})

it('should render simple form for videos without attachment markup', () => {
const rendered = new MarkdownIt({ html: true })
.use(BiDirectionalLinks({ dir: testdataDir }))
.render('[[foo.mp4]]')

expect(rendered).toBe('<p><video controls="true" preload="metadata"><source src="/foo.mp4"></video></p>\n')
})

it('should render simple form with custom texts', () => {
const rendered = new MarkdownIt({ html: true })
.use(BiDirectionalLinks({ dir: testdataDir }))
Expand Down
44 changes: 41 additions & 3 deletions packages/markdown-it-bi-directional-links/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { cyan, gray, yellow } from 'colorette'
import _debug from 'debug'

import packageJSON from '../package.json'
import { findBiDirectionalLinks, genImage, genLink } from './utils'
import { findBiDirectionalLinks, genAudio, genImage, genLink, genVideo } from './utils'

/** it will match [[file]] and [[file|text]] */
const biDirectionalLinkPattern = /!?\[\[([^|\]\n]+)(\|([^\]\n]+))?\]\](?!\()/
Expand Down Expand Up @@ -34,6 +34,34 @@ const IMAGES_EXTENSIONS = [
'.xbm',
]

// Web audio codec guide - Web media technologies | MDN: https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Audio_codecs
// HTML audio - Wikipedia: https://en.wikipedia.org/wiki/HTML_audio#Supported_audio_coding_formats
const AUDIO_EXTENSIONS = [
'.mp3',
'.flac',
'.wav',
'.ogg',
'.opus',
'.webm',
'.acc',
]

// Web video codec guide - Web media technologies | MDN: https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs
// HTML video - Wikipedia: https://en.wikipedia.org/wiki/HTML_video#Browser_support
//
// Test videos:
// - Download Sample Videos / Dummy Videos For Demo Use https://sample-videos.com/
// - Download MP4 files for Testing - Online Test Case https://onlinetestcase.com/mp4-file/
const VIDEOS_EXTENSIONS = [
'.mp4',
'.webm',
'.mov',
'.mkv',
'.ogg',
'.3gp',
'.flv',
]

const debug = _debug(packageJSON.name)
const logModulePrefix = `${cyan(packageJSON.name)}${gray(':')}`

Expand Down Expand Up @@ -148,7 +176,7 @@ export interface BiDirectionalLinksOptions {
/**
* The glob patterns to search for bi-directional linked files.
*
* @default '*.md, *.png, *.jpg, *.jpeg, *.gif, *.svg, *.webp, *.ico, *.bmp, *.tiff, *.apng, *.avif, *.jfif, *.pjpeg, *.pjp, *.png, *.svg, *.webp, *.xbm'
* @default '*.md, *.png, *.jpg, *.jpeg, *.gif, *.svg, *.webp, *.ico, *.bmp, *.tiff, *.apng, *.avif, *.jfif, *.pjpeg, *.pjp, *.png, *.svg, *.webp, *.xbm, *.mp3, *.flac, *.wav, *.ogg, *.opus, *.mp4, *.webm, *.acc, *.mp4, *.webm, *.mov, *.mkv, *.ogg'
*/
includesPatterns?: string[]
/**
Expand Down Expand Up @@ -186,6 +214,8 @@ export const BiDirectionalLinks: (options?: BiDirectionalLinksOptions) => (md: M
if (includes.length === 0) {
includes.push('**/*.md')
IMAGES_EXTENSIONS.forEach(ext => includes.push(`**/*${ext}`))
AUDIO_EXTENSIONS.forEach(ext => includes.push(`**/*${ext}`))
VIDEOS_EXTENSIONS.forEach(ext => includes.push(`**/*${ext}`))
}

const files = globSync(includes, {
Expand Down Expand Up @@ -259,6 +289,8 @@ export const BiDirectionalLinks: (options?: BiDirectionalLinksOptions) => (md: M
const text = link[3]?.trim() ?? ''

const isImageRef = IMAGES_EXTENSIONS.some(ext => href.endsWith(ext))
const isVideoRef = VIDEOS_EXTENSIONS.some(ext => href.endsWith(ext))
const isAudioRef = AUDIO_EXTENSIONS.some(ext => href.endsWith(ext))

// Extract the pathname from the href
const parsedHref = new URL(href, 'https://a.com')
Expand All @@ -270,7 +302,7 @@ export const BiDirectionalLinks: (options?: BiDirectionalLinksOptions) => (md: M
let osSpecificHref = parsedPathname.split('/').join(sep)

// if osSpecificHref has no extension, suffix it with .md
if (!isImageRef && (extname(osSpecificHref) === '' || extname(osSpecificHref) !== '.md'))
if (!isImageRef && !isAudioRef && !isVideoRef && (extname(osSpecificHref) === '' || extname(osSpecificHref) !== '.md'))
osSpecificHref += '.md'

const matchedHref = findBiDirectionalLinks(possibleBiDirectionalLinksInCleanBaseNameOfFilePaths, possibleBiDirectionalLinksInFullFilePaths, osSpecificHref)
Expand All @@ -291,6 +323,12 @@ export const BiDirectionalLinks: (options?: BiDirectionalLinksOptions) => (md: M
if (isImageRef) {
genImage(state, resolvedNewHref, text, link)
}
else if (isAudioRef) {
genAudio(state, resolvedNewHref, text, link)
}
else if (isVideoRef) {
genVideo(state, resolvedNewHref, text, link)
}
else {
resolvedNewHref = resolvedNewHref + parsedHref.search + parsedHref.hash
genLink(state, resolvedNewHref, text, md, href, link)
Expand Down
Binary file not shown.
Binary file not shown.
40 changes: 40 additions & 0 deletions packages/markdown-it-bi-directional-links/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,43 @@ export function genImage(

state.pos += link![0].length
}

export function genVideo(
state: StateInline,
resolvedNewHref: string,
text: string,
link: RegExpMatchArray,
) {
const openToken = state.push('video_open', 'video', 1)
openToken.attrSet('controls', 'true')
openToken.attrSet('preload', 'metadata')
if (text)
openToken.attrSet('aria-label', text)

const sourceOpenToken = state.push('source_open', 'source', 1)
sourceOpenToken.attrSet('src', resolvedNewHref)

state.push('video_close', 'video', -1)

state.pos += link![0].length
}

export function genAudio(
state: StateInline,
resolvedNewHref: string,
text: string,
link: RegExpMatchArray,
) {
const openToken = state.push('audio_open', 'audio', 1)
openToken.attrSet('controls', 'true')
openToken.attrSet('preload', 'metadata')
if (text)
openToken.attrSet('aria-label', text)

const sourceOpenToken = state.push('source_open', 'source', 1)
sourceOpenToken.attrSet('src', resolvedNewHref)

state.push('audio_close', 'audio', -1)

state.pos += link![0].length
}

0 comments on commit e49ec42

Please sign in to comment.