diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index c6c8b36..0000000 --- a/.editorconfig +++ /dev/null @@ -1,9 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/.github/workflows/bb.yml b/.github/workflows/bb.yml deleted file mode 100644 index 0198fc3..0000000 --- a/.github/workflows/bb.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: bb -on: - issues: - types: [opened, reopened, edited, closed, labeled, unlabeled] - pull_request_target: - types: [opened, reopened, edited, closed, labeled, unlabeled] -jobs: - main: - runs-on: ubuntu-latest - steps: - - uses: unifiedjs/beep-boop-beta@main - with: - repo-token: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index fe284ad..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: main -on: - - pull_request - - push -jobs: - main: - name: ${{matrix.node}} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: dcodeIO/setup-node-nvm@master - with: - node-version: ${{matrix.node}} - - run: npm install - - run: npm test - - uses: codecov/codecov-action@v1 - strategy: - matrix: - node: - - lts/erbium - - node diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 53a29e3..0000000 --- a/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -coverage/ -node_modules/ -.DS_Store -*.d.ts -*.log -yarn.lock diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 43c97e7..0000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index e7939c4..0000000 --- a/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -coverage/ -*.json -*.md diff --git a/index.js b/index.js deleted file mode 100644 index de75166..0000000 --- a/index.js +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('hast').Properties} Properties - * @typedef {import('hast').Element['children'][number]} ElementChild - * - * @typedef Options - * Configuration. - * @property {'_self'|'_blank'|'_parent'|'_top'|false} [target='_blank'] - * How to display referenced documents (`string?`: `_self`, `_blank`, - * `_parent`, or `_top`, default: `_blank`). - * Pass `false` to not set `target`s on links. - * @property {string[]|string|false} [rel=['nofollow', 'noopener', 'noreferrer']] - * Link types to hint about the referenced documents. - * Pass `false` to not set `rel`s on links. - * - * > When using a `target`, add `noopener` and `noreferrer` to avoid - * > exploitation of the `window.opener` API. - * @property {string[]} [protocols=['http', 'https']] - * Protocols to check, such as `mailto` or `tel`. - * @property {ElementChild|ElementChild[]} [content] - * hast content to insert at the end of external links. - * Will be inserted in a `` element. - * - * Useful for improving accessibility by [giving users advanced warning when - * opening a new window. - * @property {Properties} [contentProperties] - * `Properties` to add to the `span` wrapping `content`, when given. - */ - -import {visit} from 'unist-util-visit' -import {definitions} from 'mdast-util-definitions' -import {parse} from 'space-separated-tokens' -import absolute from 'is-absolute-url' -import extend from 'extend' - -const defaultTarget = '_blank' -const defaultRel = ['nofollow', 'noopener', 'noreferrer'] -const defaultProtocols = ['http', 'https'] - -/** - * Plugin to automatically add `target` and `rel` attributes to external links. - * - * @type {import('unified').Plugin<[Options?]|void[], Root>} - */ -export default function remarkExternalLinks(options = {}) { - const target = options.target - const rel = typeof options.rel === 'string' ? parse(options.rel) : options.rel - const protocols = options.protocols || defaultProtocols - const content = - options.content && !Array.isArray(options.content) - ? [options.content] - : options.content - const contentProperties = options.contentProperties || {} - - return (tree) => { - const definition = definitions(tree) - - visit(tree, (node) => { - if (node.type === 'link' || node.type === 'linkReference') { - const ctx = node.type === 'link' ? node : definition(node.identifier) - - // Undefined references can be injected into the tree by plugins. - /* c8 ignore next */ - if (!ctx) return - - const protocol = ctx.url.slice(0, ctx.url.indexOf(':')) - - if (absolute(ctx.url) && protocols.includes(protocol)) { - const data = node.data || (node.data = {}) - const props = /** @type {Properties} */ ( - data.hProperties || (data.hProperties = {}) - ) - - if (target !== false) { - props.target = target || defaultTarget - } - - if (rel !== false) { - props.rel = (rel || defaultRel).concat() - } - - if (content) { - // `fragment` is not a known mdast node, but unknown nodes with - // children are handled as elements by `mdast-util-to-hast`: - // See: . - node.children.push({ - // @ts-expect-error - type: 'fragment', - children: [], - data: { - hName: 'span', - hProperties: extend(true, contentProperties), - hChildren: extend(true, content) - } - }) - } - } - } - }) - } -} diff --git a/license b/license deleted file mode 100644 index aa0cee1..0000000 --- a/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2017 Cédric Delpoux - -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. diff --git a/package.json b/package.json index 4d7b30a..f102b75 100644 --- a/package.json +++ b/package.json @@ -1,85 +1,6 @@ { + "bugs": "https://github.com/remarkjs/remark-external-links/issues", "name": "remark-external-links", - "version": "9.0.1", - "description": "Legacy remark plugin to automatically add target and rel attributes to external links — please use `rehype-external-links`", - "license": "MIT", - "keywords": [], "repository": "remarkjs/remark-external-links", - "bugs": "https://github.com/remarkjs/remark-external-links/issues", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "author": "Cédric Delpoux ", - "contributors": [ - "Cédric Delpoux ", - "Titus Wormer (https://wooorm.com)", - "Merlijn Vos ", - "Takayosi Amagi ", - "Zach Schnackel ", - "Tsuyusato Kitsune ", - "Matsuko Friedland " - ], - "sideEffects": false, - "type": "module", - "main": "index.js", - "types": "index.d.ts", - "files": [ - "index.d.ts", - "index.js" - ], - "dependencies": { - "@types/hast": "^2.3.2", - "@types/mdast": "^3.0.0", - "extend": "^3.0.0", - "is-absolute-url": "^4.0.0", - "mdast-util-definitions": "^5.0.0", - "space-separated-tokens": "^2.0.0", - "unified": "^10.0.0", - "unist-util-visit": "^4.0.0" - }, - "devDependencies": { - "@types/extend": "^3.0.1", - "@types/tape": "^4.0.0", - "c8": "^7.0.0", - "prettier": "^2.0.0", - "remark": "^14.0.0", - "remark-cli": "^10.0.0", - "remark-html": "^14.0.0", - "remark-preset-wooorm": "^9.0.0", - "rimraf": "^3.0.0", - "tape": "^5.0.0", - "type-coverage": "^2.0.0", - "typescript": "^4.0.0", - "xo": "^0.44.0" - }, - "scripts": { - "build": "rimraf \"*.d.ts\" && tsc && type-coverage", - "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", - "test-api": "node --conditions development test.js", - "test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov npm run test-api", - "test": "npm run build && npm run format && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - }, - "typeCoverage": { - "atLeast": 100, - "detail": true, - "strict": true, - "ignoreCatch": true - } + "version": "10.0.0" } diff --git a/readme.md b/readme.md index 5ef8030..08d3c09 100644 --- a/readme.md +++ b/readme.md @@ -1,24 +1,12 @@ # remark-external-links -**Stability: Legacy**. -This package is no longer recommended for use. -It’s still covered by semantic-versioning guarantees and not yet deprecated, -but use of this package should be avoided. +Deprecated: this package is no longer maintained. Please use `remark-rehype` to move from remark (markdown) to rehype (HTML) and then replace `remark-external-links` with [`rehype-external-links`][rehype-external-links]. -Legacy [documentation for this package](https://github.com/remarkjs/remark-external-links/tree/307f8dc) -is still available in Git. +[Git][] is still intact and previous versions can still be used without warnings. -## License - -[MIT][license] © [Cédric Delpoux][author] - - - -[license]: license - -[author]: https://xuopled.netlify.com +[git]: https://github.com/remarkjs/remark-external-links/tree/11bfaea [rehype-external-links]: https://github.com/rehypejs/rehype-external-links diff --git a/test.js b/test.js deleted file mode 100644 index 0fee1f4..0000000 --- a/test.js +++ /dev/null @@ -1,184 +0,0 @@ -import test from 'tape' -import {remark} from 'remark' -import html from 'remark-html' -import externalLinks from './index.js' - -const input = [ - '[remark](https://github.com/remarkjs/remark)', - '', - '[relative link](./example.md) and [fragment link](#fragment)', - '', - '[missing][], [local][], and [external][].', - '', - '[current](.) [up](..) [relative link without ./](example.md)', - '', - '[local]: #local', - '[external]: https://github.com/remarkjs/remark', - '', - '' -].join('\n') - -test('remark-external-links', (t) => { - t.equal( - remark().use(externalLinks).use(html).processSync(input).toString(), - [ - '

remark

', - '

relative link and fragment link

', - '

[missing][], local, and external.

', - '

current up relative link without ./

', - '

test@example.com

', - '' - ].join('\n'), - 'should add the defaults when without options' - ) - - t.equal( - remark() - .use(externalLinks, {target: false, rel: false}) - .use(html) - .processSync(input) - .toString(), - [ - '

remark

', - '

relative link and fragment link

', - '

[missing][], local, and external.

', - '

current up relative link without ./

', - '

test@example.com

', - '' - ].join('\n'), - 'should do nothing if both are set to false' - ) - - t.equal( - remark() - .use(externalLinks, {target: '_blank', rel: false}) - .use(html) - .processSync(input) - .toString(), - [ - '

remark

', - '

relative link and fragment link

', - '

[missing][], local, and external.

', - '

current up relative link without ./

', - '

test@example.com

', - '' - ].join('\n'), - 'should add a target' - ) - - t.equal( - remark() - .use(externalLinks, {target: false, rel: 'nofollow'}) - .use(html) - .processSync(input) - .toString(), - [ - '

remark

', - '

relative link and fragment link

', - '

[missing][], local, and external.

', - '

current up relative link without ./

', - '

test@example.com

', - '' - ].join('\n'), - 'should add a rel' - ) - - t.equal( - remark() - .use(externalLinks, {target: '_blank', rel: 'nofollow'}) - .use(html) - .processSync(input) - .toString(), - [ - '

remark

', - '

relative link and fragment link

', - '

[missing][], local, and external.

', - '

current up relative link without ./

', - '

test@example.com

', - '' - ].join('\n'), - 'should add both' - ) - - t.equal( - remark() - .use(externalLinks, {protocols: ['http', 'https', 'mailto']}) - .use(html) - .processSync(input) - .toString(), - [ - '

remark

', - '

relative link and fragment link

', - '

[missing][], local, and external.

', - '

current up relative link without ./

', - '

test@example.com

', - '' - ].join('\n'), - 'should add a target' - ) - - t.equal( - remark() - .use(externalLinks, { - content: {type: 'text', value: ' (opens in a new window)'} - }) - .use(html) - .processSync(input) - .toString(), - [ - '

remark (opens in a new window)

', - '

relative link and fragment link

', - '

[missing][], local, and external (opens in a new window).

', - '

current up relative link without ./

', - '

test@example.com

', - '' - ].join('\n'), - 'should add hast node as content' - ) - - t.equal( - remark() - .use(externalLinks, { - content: [ - {type: 'text', value: ' ('}, - { - type: 'element', - tagName: 'em', - properties: {}, - children: [{type: 'text', value: 'opens in a new window'}] - }, - {type: 'text', value: ')'} - ] - }) - .use(html) - .processSync(input) - .toString(), - [ - '

remark (opens in a new window)

', - '

relative link and fragment link

', - '

[missing][], local, and external (opens in a new window).

', - '

current up relative link without ./

', - '

test@example.com

', - '' - ].join('\n'), - 'should add hast children as content' - ) - - t.equal( - remark() - .use(externalLinks, { - contentProperties: {className: ['alpha', 'bravo']}, - content: {type: 'text', value: ' (opens in a new window)'} - }) - .use(html) - .processSync('[a](https://example.com)') - .toString(), - [ - '

a (opens in a new window)

', - '' - ].join('\n'), - 'should support `contentProperties`' - ) - - t.end() -}) diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index e31adf8..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "include": ["*.js"], - "compilerOptions": { - "target": "ES2020", - "lib": ["ES2020"], - "module": "ES2020", - "moduleResolution": "node", - "allowJs": true, - "checkJs": true, - "declaration": true, - "emitDeclarationOnly": true, - "allowSyntheticDefaultImports": true, - "skipLibCheck": true, - "strict": true - } -}