Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
remcohaszing committed Mar 23, 2024
0 parents commit 0b94eab
Show file tree
Hide file tree
Showing 70 changed files with 16,865 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .c8rc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"100": true,
"reporter": ["html", "lcov", "text"]
}
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 100
trim_trailing_whitespace = true

[COMMIT_EDITMSG]
max_line_length = 72
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.jsx
6 changes: 6 additions & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
root: true
extends:
- remcohaszing
rules:
no-param-reassign: off
import/no-extraneous-dependencies: off
79 changes: 79 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: ci

on:
pull_request:
push:
branches: [main]
tags: ['*']

jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx eslint .

pack:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm pack
- uses: actions/upload-artifact@v4
with:
name: package
path: '*.tgz'

test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version:
- 18
- 20
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm install --global npm@latest
- run: npm ci
- run: npm test
- uses: codecov/codecov-action@v4
if: ${{ matrix.node-version == 20 }}

prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx prettier --check .

release:
runs-on: ubuntu-latest
needs:
- eslint
- test
- pack
- prettier
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- uses: actions/download-artifact@v4
with: { name: package }
- run: npm publish *.tgz --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coverage/
dist/
node_modules/
*.tsbuildinfo
*.log
*.tgz
4 changes: 4 additions & 0 deletions .prettierrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
proseWrap: always
semi: false
singleQuote: true
trailingComma: none
1 change: 1 addition & 0 deletions .remarkignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fixtures/
2 changes: 2 additions & 0 deletions .remarkrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
plugins:
- remark-preset-remcohaszing
18 changes: 18 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# MIT License

Copyright © 2024 Remco Haszing

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.
109 changes: 109 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# rehype-mdx-import-media

[![github actions](https://github.com/remcohaszing/rehype-mdx-import-media/actions/workflows/ci.yaml/badge.svg)](https://github.com/remcohaszing/rehype-mdx-import-media/actions/workflows/ci.yaml)
[![codecov](https://codecov.io/gh/remcohaszing/rehype-mdx-import-media/branch/main/graph/badge.svg)](https://codecov.io/gh/remcohaszing/rehype-mdx-import-media)
[![npm version](https://img.shields.io/npm/v/rehype-mdx-import-media)](https://www.npmjs.com/package/rehype-mdx-import-media)
[![npm downloads](https://img.shields.io/npm/dm/rehype-mdx-import-media)](https://www.npmjs.com/package/rehype-mdx-import-media)

An [MDX](https://mdxjs.com) [rehype](https://github.com/rehypejs/rehype) plugin for turning media
paths into imports.

## Table of Contents

- [Installation](#installation)
- [Usage](#usage)
- [API](#api)
- [Options](#options)
- [Compatibility](#compatibility)
- [License](#license)

## Installation

```sh
npm install rehype-mdx-import-media
```

## Usage

This plugin takes HTML elements that refer to media content, and turns them into MDX expressions
that use imports. This allows bundlers to resolve media you referenced from your code. Note that JSX
elements are **not** HTML elements, so they are not processed. HTML elements can come from:

- Markdown syntax in MDX files, such as images.
- HTML in files parsed using the `md` [format](https://mdxjs.com/packages/mdx/#processoroptions)
when using [`rehype-raw`](https://github.com/rehypejs/rehype-raw)
- Custom remark / rehype plugins.

If this plugin finds an attribute to process, it transforms the
[hast](https://github.com/syntax-tree/hast) [`element`](https://github.com/syntax-tree/hast#element)
nodes into an
[`mdxJsxFlowElement`](https://github.com/syntax-tree/mdast-util-mdx-jsx#mdxjsxflowelementhast) node.
This may prevent other rehype plugins from further processing. To avoid this, put
`rehype-mdx-import-media` after any other rehype plugins

For example, given a file named `example.mdx` with the following contents:

```mdx
![](./image.png)
```

The following script:

```js
import { compile } from '@mdx-js/mdx'
import rehypeMdxImportMedia from 'rehype-mdx-import-media'
import { read } from 'to-vfile'

const { value } = await compile(await read('example.mdx'), {
jsx: true,
rehypePlugins: [rehypeMdxImportMedia]
})
console.log(value)
```

Roughly yields:

```jsx
import _rehypeMdxImportMedia0 from './image.png'

export default function MDXContent() {
return (
<p>
<img alt="" src={_rehypeMdxImportMedia0} />
</p>
)
}
```

## API

The default export is a [rehype](https://github.com/rehypejs/rehype) plugin.

### Options

- `attributes` (`object`): HTML element attributes that should be processed. The key is the HTML
element tag name. The value is a list of attribute names to process. The default attributes are:
- [`audio[src]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#src)
- [`embed[src]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed#src)
- [`img[src]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#src)
- [`img[srcset]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#srcset)
- [`object[data]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object#data)
- [`source[src]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source#src)
- [`source[srcset]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source#srcset)
- [`track[src]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track#src)
- [`video[poster]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#poster)
- [`video[src]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#src)
- `elementAttributeNameCase` (`'html' | 'react'`): The casing to use for attribute names. This
should match the elementAttributeNameCase value passed to MDX. (Default: `'react'`)
- `resolve` (`boolean`): By default imports are resolved relative to the markdown file. This matches
default markdown behaviour. If this is set to false, this behaviour is removed and URLs are no
longer processed. This allows to import images from `node_modules`. If this is disabled, local
images can still be imported by prepending the path with `./.`. (Default: `true`).

## Compatibility

This project is compatible with MDX 3 and Node.js 18 or greater.

## License

[MIT](LICENSE.md) © [Remco Haszing](https://github.com/remcohaszing)
25 changes: 25 additions & 0 deletions fixtures/alt/expected.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*@jsxRuntime automatic*/
/*@jsxImportSource react*/
import _rehypeMdxImportMedia0 from './image.png'
function _createMdxContent(props) {
const _components = {
img: 'img',
p: 'p',
...props.components
}
return (
<_components.p>
<_components.img src={_rehypeMdxImportMedia0} alt="Alt text" />
</_components.p>
)
}
export default function MDXContent(props = {}) {
const { wrapper: MDXLayout } = props.components || {}
return MDXLayout ? (
<MDXLayout {...props}>
<_createMdxContent {...props} />
</MDXLayout>
) : (
_createMdxContent(props)
)
}
1 change: 1 addition & 0 deletions fixtures/alt/input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
![Alt text](image.png)
1 change: 1 addition & 0 deletions fixtures/alt/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
30 changes: 30 additions & 0 deletions fixtures/custom-attributes/expected.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*@jsxRuntime automatic*/
/*@jsxImportSource react*/
import _rehypeMdxImportMedia0 from './script.js'
function _createMdxContent(props) {
const _components = {
img: 'img',
p: 'p',
script: 'script',
...props.components
}
return (
<>
<_components.p>
<_components.img src="./hello.png" alt="" />
</_components.p>
{'\n'}
<_components.script src={_rehypeMdxImportMedia0} />
</>
)
}
export default function MDXContent(props = {}) {
const { wrapper: MDXLayout } = props.components || {}
return MDXLayout ? (
<MDXLayout {...props}>
<_createMdxContent {...props} />
</MDXLayout>
) : (
_createMdxContent(props)
)
}
3 changes: 3 additions & 0 deletions fixtures/custom-attributes/input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
![](./hello.png)

<script src="./script.js"></script>
5 changes: 5 additions & 0 deletions fixtures/custom-attributes/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"attributes": {
"script": "src"
}
}
40 changes: 40 additions & 0 deletions fixtures/duplicate/expected.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*@jsxRuntime automatic*/
/*@jsxImportSource react*/
import _rehypeMdxImportMedia0 from './image.png'
import _rehypeMdxImportMedia1 from './image.jpg'
function _createMdxContent(props) {
const _components = {
img: 'img',
p: 'p',
...props.components
}
return (
<>
<_components.p>
<_components.img src={_rehypeMdxImportMedia0} alt="" />
</_components.p>
{'\n'}
<_components.p>
<_components.img src={_rehypeMdxImportMedia0} alt="" />
</_components.p>
{'\n'}
<_components.p>
<_components.img src={_rehypeMdxImportMedia1} alt="" />
</_components.p>
{'\n'}
<_components.p>
<_components.img src={_rehypeMdxImportMedia1} alt="" />
</_components.p>
</>
)
}
export default function MDXContent(props = {}) {
const { wrapper: MDXLayout } = props.components || {}
return MDXLayout ? (
<MDXLayout {...props}>
<_createMdxContent {...props} />
</MDXLayout>
) : (
_createMdxContent(props)
)
}
7 changes: 7 additions & 0 deletions fixtures/duplicate/input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
![](image.png)

![](image.png)

![](image.jpg)

![](image.jpg)
1 change: 1 addition & 0 deletions fixtures/duplicate/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}

0 comments on commit 0b94eab

Please sign in to comment.