Skip to content

Commit e711141

Browse files
Initial release to add target and rel on external links
0 parents  commit e711141

17 files changed

+5703
-0
lines changed

.editorconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 2
7+
indent_style = space
8+
quote_type = single
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true

.eslintrc

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"root": true,
3+
"env": {
4+
"es6": true,
5+
"node": true,
6+
"mocha": true
7+
},
8+
"extends": [
9+
"eslint:recommended"
10+
],
11+
"overrides": [
12+
{
13+
"files": [
14+
"*.ts",
15+
"*.tsx"
16+
],
17+
"parser": "@typescript-eslint/parser",
18+
"plugins": [
19+
"@typescript-eslint"
20+
],
21+
"extends": [
22+
"plugin:@typescript-eslint/recommended"
23+
]
24+
}
25+
]
26+
}

.gitattributes

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Set the default behavior, in case people don't have `core.autocrlf` set.
2+
* text=auto
3+
4+
# Declare files that will always have LF line endings on checkout.
5+
*.ts text eol=lf
6+
7+
# Remove files for archives generated using `git archive`.
8+
.* export-ignore
9+
appveyor.yml export-ignore
10+
package-lock.json export-ignore
11+
src export-ignore
12+
test export-ignore
13+
tsconfig.json export-ignore
14+
types/index.test-d.ts export-ignore

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.DS_Store
2+
node_modules
3+
npm-debug.log
4+
yarn-error.log

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# markdown-it-external-link changelog
2+
3+
## 1.0.0 - Aug 24, 2023
4+
5+
- Initial Release

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2023 TrunkCode
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# markdown-it-external-link
2+
3+
[![NPM version][npm-image]][npm-url]
4+
[![Downloads][downloads-image]][npm-url]
5+
[![AppVeyor Build Status][appveyor-image]][appveyor-url]
6+
7+
[markdown-it](https://www.npmjs.com/package/markdown-it) plugin that adds `target` and `rel` attributes on external links.
8+
9+
## Install
10+
11+
Via `npm`
12+
13+
```bash
14+
npm install markdown-it-external-link
15+
```
16+
17+
Via Yarn
18+
19+
```bash
20+
yarn add markdown-it-external-link
21+
```
22+
23+
## Usage
24+
25+
```javascript
26+
const markdownit = require('markdown-it');
27+
const markdownitExternalLink = require('../index').default;
28+
const md = markdownit();
29+
30+
const testString = 'This is an [Example](http://example.com) link, [Google](https://google.com) link, [Facebook](https://facebook.com) link, [Test Example](http://test.example.com/) link, [Test2 Example](http://test2.example.com/) link and [Relative](/docs/concept/) link.';
31+
32+
// Mark http://example.com and http://test.example.com as internal domain.
33+
md.use(markdownitExternalLink, {
34+
'hosts': [
35+
'http://example.com',
36+
'http://test.example.com'
37+
]
38+
});
39+
40+
console.log(md.render(testString));
41+
```
42+
43+
## Parameters
44+
45+
| Attributes | Type | Required | Default | Description |
46+
|:--------------:|:------:|:--------:|:----------:|:--------------------------------------------------------------------------------:|
47+
| hosts | Array | Yes | [] | Site hostname(s) to detect external links. |
48+
| target | String | No | `_blank` | Specifies where to open the linked document. |
49+
| rel | String | No | `noopener` | Specifies the relationship between the current document and the linked document. |
50+
51+
[npm-image]: https://img.shields.io/npm/v/markdown-it-external-link.svg
52+
[npm-url]: https://www.npmjs.com/package/markdown-it-external-link
53+
[downloads-image]: https://img.shields.io/npm/dm/markdown-it-external-link.svg
54+
55+
[appveyor-url]: https://ci.appveyor.com/project/trunkcode/markdown-it-external-link
56+
[appveyor-image]: https://img.shields.io/appveyor/ci/trunkcode/markdown-it-external-link.svg?label=appveyor

appveyor.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
version: "{build}"
2+
3+
# branches to build
4+
branches:
5+
only:
6+
- main
7+
8+
environment:
9+
matrix:
10+
# node.js
11+
- nodejs_version: "16"
12+
- nodejs_version: "18"
13+
- nodejs_version: ""
14+
15+
install:
16+
- ps: Install-Product node $env:nodejs_version
17+
- npm install
18+
19+
test_script:
20+
- npm run lint
21+
- npm run test
22+
23+
build: off

index.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
const detect_external_link_1 = __importDefault(require("detect-external-link"));
7+
function markdownitExternalLink(md, userConfig) {
8+
const defaultConfig = {
9+
hosts: [],
10+
rel: 'noopener',
11+
target: '_blank',
12+
};
13+
const defaultOpenRender = md.renderer.rules.link_open || function (tokens, idx, options, env, self) {
14+
return self.renderToken(tokens, idx, options);
15+
};
16+
const finalConfig = Object.assign({}, defaultConfig, userConfig);
17+
md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
18+
if (tokens[idx] && tokens[idx].attrs) {
19+
const linkIndex = tokens[idx].attrIndex('href');
20+
if (linkIndex in tokens[idx].attrs && tokens[idx].attrs[linkIndex][1]) {
21+
if ((0, detect_external_link_1.default)(tokens[idx].attrs[linkIndex][1], finalConfig)) {
22+
const relIndex = tokens[idx].attrIndex('rel');
23+
const targetIndex = tokens[idx].attrIndex('target');
24+
if (targetIndex < 0) {
25+
tokens[idx].attrPush(['target', finalConfig.target]);
26+
}
27+
else {
28+
tokens[idx].attrs[targetIndex][1] = finalConfig.target;
29+
}
30+
if (relIndex < 0) {
31+
tokens[idx].attrPush(['rel', finalConfig.rel]);
32+
}
33+
else {
34+
tokens[idx].attrs[relIndex][1] = finalConfig.rel;
35+
}
36+
}
37+
}
38+
}
39+
return defaultOpenRender(tokens, idx, options, env, self);
40+
};
41+
}
42+
exports.default = markdownitExternalLink;

0 commit comments

Comments
 (0)