Socket
Socket
Sign inDemoInstall

markdown-it-attrs

Package Overview
Dependencies
7
Maintainers
1
Versions
59
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.1.3 to 4.1.4

15

.eslintrc.json

@@ -9,3 +9,3 @@ {

},
"extends": "eslint:recommended",
"extends": [ "eslint:recommended" ],
"rules": {

@@ -33,4 +33,15 @@ "indent": [

],
"no-var": "error"
"no-var": "error",
"prefer-const": "error",
"no-else-return": "error",
"default-case": "error",
"consistent-return": "error",
"no-restricted-syntax": [
"error",
{
"selector": "ForInStatement",
"message": "for..in loops iterate over the entire prototype chain. Use Object.{keys,values,entries}."
}
]
}
}

4

debug.js

@@ -7,3 +7,3 @@ /* eslint-env es6 */

let src = `header1 | header2
const src = `header1 | header2
------- | -------

@@ -15,4 +15,4 @@ column1 | column2

let res = md.render(src);
const res = md.render(src);
console.log(res); // eslint-disable-line

@@ -1,3 +0,3 @@

let md = require('markdown-it')();
let markdownItAttrs = require('markdown-it-attrs');
const md = require('markdown-it')();
const markdownItAttrs = require('markdown-it-attrs');

@@ -4,0 +4,0 @@ md.use(markdownItAttrs);

@@ -18,10 +18,10 @@ 'use strict';

function curlyAttrs(state) {
let tokens = state.tokens;
const tokens = state.tokens;
for (let i = 0; i < tokens.length; i++) {
for (let p = 0; p < patterns.length; p++) {
let pattern = patterns[p];
const pattern = patterns[p];
let j = null; // position of child with offset 0
let match = pattern.tests.every(t => {
let res = test(tokens, i, t);
const match = pattern.tests.every(t => {
const res = test(tokens, i, t);
if (res.j !== null) { j = res.j; }

@@ -53,3 +53,3 @@ return res.match;

function test(tokens, i, t) {
let res = {
const res = {
match: false,

@@ -59,3 +59,3 @@ j: null // position of child

let ii = t.shift !== undefined
const ii = t.shift !== undefined
? i + t.shift

@@ -69,3 +69,3 @@ : t.position;

let token = get(tokens, ii); // supports negative ii
const token = get(tokens, ii); // supports negative ii

@@ -75,3 +75,3 @@

for (let key in t) {
for (const key of Object.keys(t)) {
if (key === 'shift' || key === 'position') { continue; }

@@ -86,4 +86,4 @@

let match;
let childTests = t.children;
let children = token.children;
const childTests = t.children;
const children = token.children;
if (childTests.every(tt => tt.position !== undefined)) {

@@ -94,3 +94,3 @@ // positions instead of shifts, do not loop all children

// we may need position of child in transform
let j = last(childTests).position;
const j = last(childTests).position;
res.j = j >= 0 ? j : children.length + j;

@@ -125,3 +125,3 @@ }

if (isArrayOfFunctions(t[key])) {
let r = t[key].every(tt => tt(token[key]));
const r = t[key].every(tt => tt(token[key]));
if (r === false) { return res; }

@@ -128,0 +128,0 @@ break;

@@ -84,3 +84,5 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.markdownItAttrs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){

var _loop2 = function _loop2(key) {
var _loop2 = function _loop2() {
var key = _Object$keys[_i];
if (key === 'shift' || key === 'position') {

@@ -202,4 +204,4 @@ return "continue";

for (var key in t) {
var _ret = _loop2(key);
for (var _i = 0, _Object$keys = Object.keys(t); _i < _Object$keys.length; _i++) {
var _ret = _loop2();

@@ -569,3 +571,4 @@ if (_ret === "continue") continue;

},{"./utils.js":3}],3:[function(require,module,exports){
'use strict';
"use strict";
/**

@@ -577,3 +580,2 @@ * parse {.class #id key=val} strings

*/
exports.getAttrs = function (str, start, options) {

@@ -680,5 +682,5 @@ // not tab, line feed, form feed, space, solidus, greater than sign, quotation mark, apostrophe and equals sign

});
} else {
return attrs;
}
return attrs;
};

@@ -712,7 +714,6 @@ /**

* start: '{.a} asdf'
* middle: 'a{.b}c'
* end: 'asdf {.a}'
* only: '{.a}'
*
* @param {string} where to expect {} curly. start, middle, end or only.
* @param {string} where to expect {} curly. start, end or only.
* @return {function(string)} Function which testes if string has curly.

@@ -724,3 +725,3 @@ */

if (!where) {
throw new Error('Parameter `where` not passed. Should be "start", "middle", "end" or "only".');
throw new Error('Parameter `where` not passed. Should be "start", "end" or "only".');
}

@@ -779,2 +780,5 @@ /**

break;
default:
throw new Error("Unexpected case ".concat(where, ", expected 'start', 'end' or 'only'"));
}

@@ -833,2 +837,4 @@

}
return false;
};

@@ -835,0 +841,0 @@ /**

{
"name": "markdown-it-attrs",
"version": "4.1.3",
"version": "4.1.4",
"description": "Add classes, identifiers and attributes to your markdown with {} curly brackets, similar to pandoc's header attributes",

@@ -45,3 +45,3 @@ "main": "index.js",

"eslint": "^8.4.1",
"markdown-it": "^12.2.0",
"markdown-it": "^13.0.1",
"markdown-it-implicit-figures": "^0.9.0",

@@ -53,5 +53,5 @@ "markdown-it-katex": "^2.0.3",

"peerDependencies": {
"markdown-it": ">= 9.0.0 < 13.0.0"
"markdown-it": ">= 9.0.0"
},
"tonicExampleFilename": "demo.js"
}

@@ -31,5 +31,5 @@ 'use strict';

transform: (tokens, i) => {
let token = tokens[i];
let start = token.info.lastIndexOf(options.leftDelimiter);
let attrs = utils.getAttrs(token.info, start, options);
const token = tokens[i];
const start = token.info.lastIndexOf(options.leftDelimiter);
const attrs = utils.getAttrs(token.info, start, options);
utils.addAttrs(attrs, token);

@@ -63,6 +63,6 @@ token.info = utils.removeDelimiter(token.info, options);

transform: (tokens, i, j) => {
let token = tokens[i].children[j];
let endChar = token.content.indexOf(options.rightDelimiter);
let attrToken = tokens[i].children[j - 1];
let attrs = utils.getAttrs(token.content, 0, options);
const token = tokens[i].children[j];
const endChar = token.content.indexOf(options.rightDelimiter);
const attrToken = tokens[i].children[j - 1];
const attrs = utils.getAttrs(token.content, 0, options);
utils.addAttrs(attrs, attrToken);

@@ -100,5 +100,5 @@ if (token.content.length === (endChar + options.rightDelimiter.length)) {

transform: (tokens, i) => {
let token = tokens[i + 2];
let tableOpen = utils.getMatchingOpeningToken(tokens, i);
let attrs = utils.getAttrs(token.content, 0, options);
const token = tokens[i + 2];
const tableOpen = utils.getMatchingOpeningToken(tokens, i);
const attrs = utils.getAttrs(token.content, 0, options);
// add attributes

@@ -131,6 +131,6 @@ utils.addAttrs(attrs, tableOpen);

transform: (tokens, i, j) => {
let token = tokens[i].children[j];
let content = token.content;
let attrs = utils.getAttrs(content, 0, options);
let openingToken = utils.getMatchingOpeningToken(tokens[i].children, j - 1);
const token = tokens[i].children[j];
const content = token.content;
const attrs = utils.getAttrs(content, 0, options);
const openingToken = utils.getMatchingOpeningToken(tokens[i].children, j - 1);
utils.addAttrs(attrs, openingToken);

@@ -165,5 +165,5 @@ token.content = content.slice(content.indexOf(options.rightDelimiter) + options.rightDelimiter.length);

transform: (tokens, i, j) => {
let token = tokens[i].children[j];
let content = token.content;
let attrs = utils.getAttrs(content, 0, options);
const token = tokens[i].children[j];
const content = token.content;
const attrs = utils.getAttrs(content, 0, options);
let ii = i - 2;

@@ -207,6 +207,6 @@ while (tokens[ii - 1] &&

transform: (tokens, i) => {
let token = tokens[i + 2];
let content = token.content;
let attrs = utils.getAttrs(content, 0, options);
let openingToken = utils.getMatchingOpeningToken(tokens, i);
const token = tokens[i + 2];
const content = token.content;
const attrs = utils.getAttrs(content, 0, options);
const openingToken = utils.getMatchingOpeningToken(tokens, i);
utils.addAttrs(attrs, openingToken);

@@ -237,7 +237,7 @@ tokens.splice(i + 1, 3);

transform: (tokens, i, j) => {
let token = tokens[i].children[j];
let content = token.content;
let attrs = utils.getAttrs(content, content.lastIndexOf(options.leftDelimiter), options);
const token = tokens[i].children[j];
const content = token.content;
const attrs = utils.getAttrs(content, content.lastIndexOf(options.leftDelimiter), options);
utils.addAttrs(attrs, tokens[i - 2]);
let trimmed = content.slice(0, content.lastIndexOf(options.leftDelimiter));
const trimmed = content.slice(0, content.lastIndexOf(options.leftDelimiter));
token.content = last(trimmed) !== ' ' ?

@@ -269,8 +269,8 @@ trimmed : trimmed.slice(0, -1);

transform: (tokens, i, j) => {
let token = tokens[i].children[j];
let attrs = utils.getAttrs(token.content, 0, options);
const token = tokens[i].children[j];
const attrs = utils.getAttrs(token.content, 0, options);
// find last closing tag
let ii = i + 1;
while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) { ii++; }
let openingToken = utils.getMatchingOpeningToken(tokens, ii);
const openingToken = utils.getMatchingOpeningToken(tokens, ii);
utils.addAttrs(attrs, openingToken);

@@ -301,9 +301,9 @@ tokens[i].children = tokens[i].children.slice(0, -2);

transform: (tokens, i) => {
let token = tokens[i];
const token = tokens[i];
token.type = 'hr';
token.tag = 'hr';
token.nesting = 0;
let content = tokens[i + 1].content;
let start = content.lastIndexOf(options.leftDelimiter);
let attrs = utils.getAttrs(content, start, options);
const content = tokens[i + 1].content;
const start = content.lastIndexOf(options.leftDelimiter);
const attrs = utils.getAttrs(content, start, options);
utils.addAttrs(attrs, token);

@@ -332,10 +332,10 @@ token.markup = content;

transform: (tokens, i, j) => {
let token = tokens[i].children[j];
let content = token.content;
let attrs = utils.getAttrs(content, content.lastIndexOf(options.leftDelimiter), options);
const token = tokens[i].children[j];
const content = token.content;
const attrs = utils.getAttrs(content, content.lastIndexOf(options.leftDelimiter), options);
let ii = i + 1;
while (tokens[ii + 1] && tokens[ii + 1].nesting === -1) { ii++; }
let openingToken = utils.getMatchingOpeningToken(tokens, ii);
const openingToken = utils.getMatchingOpeningToken(tokens, ii);
utils.addAttrs(attrs, openingToken);
let trimmed = content.slice(0, content.lastIndexOf(options.leftDelimiter));
const trimmed = content.slice(0, content.lastIndexOf(options.leftDelimiter));
token.content = last(trimmed) !== ' ' ?

@@ -342,0 +342,0 @@ trimmed : trimmed.slice(0, -1);

@@ -1,5 +0,19 @@

# markdown-it-attrs [![Build Status](https://travis-ci.org/arve0/markdown-it-attrs.svg?branch=master)](https://travis-ci.org/arve0/markdown-it-attrs) [![npm version](https://badge.fury.io/js/markdown-it-attrs.svg)](http://badge.fury.io/js/markdown-it-attrs) [![Coverage Status](https://coveralls.io/repos/github/arve0/markdown-it-attrs/badge.svg?branch=master)](https://coveralls.io/github/arve0/markdown-it-attrs?branch=master)
# markdown-it-attrs [![Build Status](https://travis-ci.org/arve0/markdown-it-attrs.svg?branch=master)](https://travis-ci.org/arve0/markdown-it-attrs) [![npm version](https://badge.fury.io/js/markdown-it-attrs.svg)](http://badge.fury.io/js/markdown-it-attrs) [![Coverage Status](https://coveralls.io/repos/github/arve0/markdown-it-attrs/badge.svg?branch=master)](https://coveralls.io/github/arve0/markdown-it-attrs?branch=master) <!-- omit in toc -->
Add classes, identifiers and attributes to your markdown with `{.class #identifier attr=value attr2="spaced value"}` curly brackets, similar to [pandoc's header attributes](http://pandoc.org/README.html#extension-header_attributes).
# Table of contents <!-- omit in toc -->
- [Examples](#examples)
- [Install](#install)
- [Support](#support)
- [Usage](#usage)
- [Security](#security)
- [Limitations](#limitations)
- [Ambiguity](#ambiguity)
- [Custom rendering](#custom-rendering)
- [Custom blocks](#custom-blocks)
- [Custom delimiters](#custom-delimiters)
- [Development](#development)
- [License](#license)
## Examples
Example input:

@@ -69,3 +83,12 @@ ```md

## Support
Library is considered done from my part. I'm maintaining it with bug fixes and
security updates.
I'll approve pull requests that are easy to understand. Generally not willing
merge pull requests that increase maintainance complexity. Feel free to open
anyhow and I'll give my feedback.
If you need some extra features, I'm available for hire.
## Usage

@@ -118,2 +141,28 @@

## Limitations
markdown-it-attrs relies on markdown parsing in markdown-it, which means some
special cases are not possible to fix. Like using `_` outside and inside
attributes:
```md
_i want [all of this](/link){target="_blank"} to be italics_
```
Above example will render to:
```html
<p>_i want <a href="/link">all of this</a>{target=&quot;<em>blank&quot;} to be italics</em></p>
```
...which is probably not what you wanted. Of course, you could use `*` for
italics to solve this parsing issue:
```md
*i want [all of this](/link){target="_blank"} to be italics*
```
Output:
```html
<p><em>i want <a href="/link" target="_blank">all of this</a> to be italics</em></p>
```
## Ambiguity

@@ -272,4 +321,29 @@ When class can be applied to both inline or block element, inline element will take precedence:

## Development
Tests are in [test.js](./test.js).
Run all tests:
```sh
npm test
```
Run particular test:
```sh
npm test -- -g "not crash"
```
In tests, use helper function `replaceDelimiters` to make test run with
different delimiters (`{}`, `[]` and `[[]]`).
For easy access to HTML output you can use [debug.js](./debug.js):
```sh
node debug.js # will print HTML output
```
Please do **not** submit pull requests with changes in package version or built
files like browser.js.
## License
MIT © [Arve Seljebu](http://arve0.github.io/)

@@ -1,2 +0,1 @@

'use strict';
/**

@@ -30,3 +29,3 @@ * parse {.class #id key=val} strings

}
let char_ = str.charAt(i);
const char_ = str.charAt(i);

@@ -95,6 +94,6 @@ // switch to reading value if equal sign

if (options.allowedAttributes && options.allowedAttributes.length) {
let allowedAttributes = options.allowedAttributes;
const allowedAttributes = options.allowedAttributes;
return attrs.filter(function (attrPair) {
let attr = attrPair[0];
const attr = attrPair[0];

@@ -110,5 +109,5 @@ function isAllowedAttribute (allowedAttribute) {

} else {
return attrs;
}
return attrs;
};

@@ -124,3 +123,3 @@

for (let j = 0, l = attrs.length; j < l; ++j) {
let key = attrs[j][0];
const key = attrs[j][0];
if (key === 'class') {

@@ -141,7 +140,6 @@ token.attrJoin('class', attrs[j][1]);

* start: '{.a} asdf'
* middle: 'a{.b}c'
* end: 'asdf {.a}'
* only: '{.a}'
*
* @param {string} where to expect {} curly. start, middle, end or only.
* @param {string} where to expect {} curly. start, end or only.
* @return {function(string)} Function which testes if string has curly.

@@ -152,3 +150,3 @@ */

if (!where) {
throw new Error('Parameter `where` not passed. Should be "start", "middle", "end" or "only".');
throw new Error('Parameter `where` not passed. Should be "start", "end" or "only".');
}

@@ -162,3 +160,3 @@

// we need minimum three chars, for example {b}
let minCurlyLength = options.leftDelimiter.length + 1 + options.rightDelimiter.length;
const minCurlyLength = options.leftDelimiter.length + 1 + options.rightDelimiter.length;
if (!str || typeof str !== 'string' || str.length < minCurlyLength) {

@@ -169,4 +167,4 @@ return false;

function validCurlyLength (curly) {
let isClass = curly.charAt(options.leftDelimiter.length) === '.';
let isId = curly.charAt(options.leftDelimiter.length) === '#';
const isClass = curly.charAt(options.leftDelimiter.length) === '.';
const isId = curly.charAt(options.leftDelimiter.length) === '#';
return (isClass || isId)

@@ -178,3 +176,3 @@ ? curly.length >= (minCurlyLength + 1)

let start, end, slice, nextChar;
let rightDelimiterMinimumShift = minCurlyLength - options.rightDelimiter.length;
const rightDelimiterMinimumShift = minCurlyLength - options.rightDelimiter.length;
switch (where) {

@@ -207,2 +205,5 @@ case 'start':

break;
default:
throw new Error(`Unexpected case ${where}, expected 'start', 'end' or 'only'`);
}

@@ -221,6 +222,6 @@

let curly = new RegExp(
const curly = new RegExp(
'[ \\n]?' + start + '[^' + start + end + ']+' + end + '$'
);
let pos = str.search(curly);
const pos = str.search(curly);

@@ -254,4 +255,4 @@ return pos !== -1 ? str.slice(0, pos) : str;

let level = tokens[i].level;
let type = tokens[i].type.replace('_close', '_open');
const level = tokens[i].level;
const type = tokens[i].type.replace('_close', '_open');

@@ -263,2 +264,4 @@ for (; i >= 0; --i) {

}
return false;
};

@@ -270,5 +273,5 @@

*/
let HTML_ESCAPE_TEST_RE = /[&<>"]/;
let HTML_ESCAPE_REPLACE_RE = /[&<>"]/g;
let HTML_REPLACEMENTS = {
const HTML_ESCAPE_TEST_RE = /[&<>"]/;
const HTML_ESCAPE_REPLACE_RE = /[&<>"]/g;
const HTML_REPLACEMENTS = {
'&': '&amp;',

@@ -275,0 +278,0 @@ '<': '&lt;',

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc