markdown-it-link-attributes
Advanced tools
Comparing version 1.0.0 to 2.0.0
62
index.js
@@ -5,19 +5,57 @@ 'use strict' | ||
function markdownitLinkAttributes (md, config) { | ||
config = config || {} | ||
function findFirstMatchingConfig (link, configs) { | ||
var i, config | ||
var href = link.attrs[link.attrIndex('href')][1] | ||
for (i = 0; i < configs.length; ++i) { | ||
config = configs[i] | ||
// if there is no pattern, config matches for all links | ||
// otherwise, only return config if href matches the pattern set | ||
if (!config.pattern || config.pattern.test(href)) { | ||
return config | ||
} | ||
} | ||
} | ||
function applyAttributes (idx, tokens, attributes) { | ||
Object.keys(attributes).forEach(function (attr) { | ||
var attrIndex | ||
var value = attributes[attr] | ||
if (attr === 'className') { | ||
// when dealing with applying classes | ||
// programatically, some programmers | ||
// may prefer to use the className syntax | ||
attr = 'class' | ||
} | ||
attrIndex = tokens[idx].attrIndex(attr) | ||
if (attrIndex < 0) { // attr doesn't exist, add new attribute | ||
tokens[idx].attrPush([attr, value]) | ||
} else { // attr already exists, overwrite it | ||
tokens[idx].attrs[attrIndex][1] = value // replace value of existing attr | ||
} | ||
}) | ||
} | ||
function markdownitLinkAttributes (md, configs) { | ||
if (!configs) { | ||
configs = [] | ||
} else { | ||
configs = Array.isArray(configs) ? configs : [configs] | ||
} | ||
Object.freeze(configs) | ||
var defaultRender = md.renderer.rules.link_open || this.defaultRender | ||
var attributes = Object.keys(config) | ||
md.renderer.rules.link_open = function (tokens, idx, options, env, self) { | ||
attributes.forEach(function (attr) { | ||
var value = config[attr] | ||
var aIndex = tokens[idx].attrIndex(attr) | ||
var config = findFirstMatchingConfig(tokens[idx], configs) | ||
var attributes = config && config.attrs | ||
if (aIndex < 0) { // attr doesn't exist, add new attribute | ||
tokens[idx].attrPush([attr, value]) | ||
} else { // attr already exists, overwrite it | ||
tokens[idx].attrs[aIndex][1] = value // replace value of existing attr | ||
} | ||
}) | ||
if (attributes) { | ||
applyAttributes(idx, tokens, attributes) | ||
} | ||
@@ -24,0 +62,0 @@ // pass token to default renderer. |
{ | ||
"name": "markdown-it-link-attributes", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"description": "A markdown-it plugin to configure the attributes for links", | ||
@@ -10,3 +10,4 @@ "main": "index.js", | ||
"lint": "standard | snazzy", | ||
"test": "npm run lint && mocha" | ||
"pretest": "npm run lint && npm run build", | ||
"test": "mocha" | ||
}, | ||
@@ -29,13 +30,13 @@ "repository": { | ||
"devDependencies": { | ||
"browserify": "^13.0.0", | ||
"chai": "^3.5.0", | ||
"chalk": "^1.1.3", | ||
"markdown-it": "^6.0.1", | ||
"mocha": "^2.4.5", | ||
"browserify": "^14.4.0", | ||
"chai": "^4.1.2", | ||
"chalk": "^2.1.0", | ||
"check-ecmascript-version-compatibility": "^0.1.1", | ||
"mocha": "^3.0.2", | ||
"rimraf": "^2.5.2", | ||
"sinon": "^1.17.3", | ||
"sinon": "^3.2.1", | ||
"sinon-chai": "^2.8.0", | ||
"snazzy": "^3.0.1", | ||
"standard": "^6.0.8", | ||
"uglify-js": "^2.6.2" | ||
"snazzy": "^7.0.0", | ||
"standard": "^10.0.3", | ||
"uglify-js": "^3.1.0" | ||
}, | ||
@@ -42,0 +43,0 @@ "standard": { |
104
README.md
@@ -16,18 +16,23 @@ # markdown-it-link-attributes | ||
### Basic Configuration | ||
You can pass an object with an attrs property. Each link parsed with this config will have the passed attributes. | ||
```js | ||
var md = require('markdown-it')() | ||
var mila = require('markdown-it-link-attributes') | ||
``` | ||
```js | ||
md.use(mila, { | ||
target: '_blank', | ||
rel: 'noopener' | ||
attrs: { | ||
target: '_blank', | ||
rel: 'noopener' | ||
} | ||
}) | ||
var html = md.render('[link](https://google.com)') | ||
html // <p><a href="https://google.com" target="_blank" rel="noopener">link</a></p> | ||
var result = md.render('[Example](https://example.com') | ||
result // <a href="https://example.com" target="_blank" rel="noopener">Example</a> | ||
``` | ||
If the `linkify` optoon is set to `true` on `markdown-it`, then the attributes will be applied to plain links as well. | ||
If the `linkify` option is set to `true` on `markdown-it`, then the attributes will be applied to plain links as well. | ||
@@ -48,7 +53,92 @@ ```js | ||
### Pattern | ||
You can also specify a pattern property. The link's href property will be checked against the pattern RegExp provided and only apply the attributes if it matches the pattern. | ||
```js | ||
md.use(mila, { | ||
pattern: /^https:/, | ||
attrs: { | ||
target: '_blank', | ||
rel: 'noopener' | ||
} | ||
}) | ||
var matchingResult = md.render('[Matching Example](https://example.com') | ||
var ignoredResult = md.render('[Not Matching Example](http://example.com') | ||
matchingResult // <a href="https://example.com" target="_blank" rel="noopener">Matching Example</a> | ||
ignoredResult // <a href="http://example.com">Not Matching Example</a> | ||
``` | ||
### Applying classes | ||
You can either apply a `class` to a link by using a `class` or a `className` property. Either one will work, but use only one, not both. | ||
```js | ||
md.use(mila, { | ||
attrs: { | ||
class: 'my-class' | ||
} | ||
}) | ||
// or | ||
md.use(mila, { | ||
attrs: { | ||
className: 'my-class' | ||
} | ||
}) | ||
``` | ||
### Multiple Configurations | ||
Alternatively, you can pass an Array of configurations. The first pattern to match will be applied to the link. | ||
```js | ||
md.use(mila, [{ | ||
pattern: /^https?:\/\//, | ||
attrs: { | ||
class: 'external-link' | ||
} | ||
}, { | ||
pattern: /^\//, | ||
attrs: { | ||
class: 'absolute-link' | ||
} | ||
}, { | ||
pattern: /blue/, | ||
attrs: { | ||
class: 'link-that-contains-the-word-blue' | ||
} | ||
}]) | ||
var externalResult = md.render('[external](https://example.com') | ||
var absoluteResult = md.render('[absolute](/some-page') | ||
var blueResult = md.render('[blue](relative/link/with/blue/in/the/name') | ||
externalResult // <a href="https://example.com" class="external-link">external</a> | ||
absoluteResult // <a href="/some-page" class="absolute-link">absolute</a> | ||
blueResult // <a href="relative/link/with/blue/in/the/name" class="link-that-contains-the-word-blue">blue</a> | ||
``` | ||
If multiple patterns match, the first configuration to match will be used. | ||
``` | ||
// This matches both the "starts with http or https" rule and the "contains the word blue" rule. | ||
// Since the http/https rule was defined first, that is the configuration that is used. | ||
var result = md.render('[external](https://example.com/blue') | ||
result // <a href="https://example.com/blue" class="external-link">external</a> | ||
``` | ||
## Usage in the browser | ||
_Differences in browser._ If you load script directly into the page, without a package system, the module will add itself globally as `window.markdownitLinkAttributes`. | ||
## Testing | ||
This plugin is tested against markdown-it @ 6,7,8 and latest | ||
## License | ||
[MIT](https://github.com/markdown-it/markdown-it-footnote/blob/master/LICENSE) |
8484
6
54
143