Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

markdown-it-attrs

Package Overview
Dependencies
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

markdown-it-attrs - npm Package Compare versions

Comparing version 0.0.3 to 0.1.0

172

index.js
'use strict';
var utils = require('./utils.js');
module.exports = function attributes(md) {
// not tab, line feed, form feed, space, solidus, greater than sign, quotation mark, apostrophe and equals sign
var allowedKeyChars = /[^\t\n\f \/>"'=]/;
var pairSeparator = ' ';
var keySeparator = '=';
var classChar = '.';
var idChar = '#';
function curlyAttrs(state){
var l = state.tokens.length;
var tokens = state.tokens;
for (var i = 0; i < l; i++) {
var l = tokens.length;
for (var i = 0; i < l; ++i) {
// block tokens contain markup
// inline tokens contain the text
if (tokens[i].type !== 'inline') {

@@ -21,90 +18,49 @@ continue;

var inlineTokens = tokens[i].children;
if (inlineTokens.length <= 0) {
if (!inlineTokens || inlineTokens.length <= 0) {
continue;
}
var end = inlineTokens.length - 1;
var content = inlineTokens[end].content;
// should end in }
if (content.charAt(content.length - 1) !== '}') {
continue;
}
var curlyStart = content.indexOf('{');
// should start with {
if (curlyStart === -1) {
continue;
}
var key = '';
var value = '';
var parsingKey = true;
var valueInsideQuotes = false;
// read inside {}, excluding {, including }
for (var ii = curlyStart + 1; ii < content.length; ii++) {
var char = content.charAt(ii);
// switch to reading value if equal sign
if (char === keySeparator) {
parsingKey = false;
// attributes in inline tokens
for (var j=0, k=inlineTokens.length; j<k; ++j) {
// should be inline token of type text
if (!inlineTokens[j] || inlineTokens[j].type !== 'text') {
continue;
}
// {.class}
if (char === classChar && key === '') {
key = 'class';
parsingKey = false;
// token before should not be opening
if (!inlineTokens[j - 1] || inlineTokens[j - 1].nesting === 1) {
continue;
}
// {#id}
if (char === idChar && key === '') {
key = 'id';
parsingKey = false;
// token should contain { in begining
if (inlineTokens[j].content[0] !== '{') {
continue;
}
// {value="inside quotes"}
if (char === '"' && value === '') {
valueInsideQuotes = true;
// } should be found
var endChar = inlineTokens[j].content.indexOf('}');
if (endChar === -1) {
continue;
}
if (char === '"' && valueInsideQuotes) {
valueInsideQuotes = false;
// which token to add attributes to
var attrToken = matchingOpeningToken(inlineTokens, j - 1);
if (!attrToken) {
continue;
}
// read next key/value pair
if ((char === pairSeparator && !valueInsideQuotes) ||
char === '}') {
if (key === 'class' &&
tokens[i - 1].attrIndex(key) !== -1) {
var classIdx = tokens[i - 1].attrIndex(key);
tokens[i - 1].attrs[classIdx][1] += ' ' + value;
} else {
tokens[i - 1].attrPush([key, value]);
}
key = '';
value = '';
parsingKey = true;
continue;
var attrs = utils.getAttrs(inlineTokens[j].content, 1, endChar);
if (attrs.length !== 0) {
// remove {}
inlineTokens[j].content = inlineTokens[j].content.substr(endChar + 1);
// add attributes
utils.addAttrs(attrs, attrToken);
}
}
// continue if character not allowed
if (parsingKey && char.search(allowedKeyChars) === -1) {
continue;
}
// no other conditions met; append to key/value
if (parsingKey) {
key += char;
continue;
}
value += char;
// attributes for blocks
if (hasCurlyEnd(tokens[i])) {
var content = last(inlineTokens).content;
var curlyStart = content.lastIndexOf('{');
var attrs = utils.getAttrs(content, curlyStart + 1, content.length - 1);
// some blocks are hidden, example li > paragraph_open
utils.addAttrs(attrs, firstTokenNotHidden(tokens, i - 1));
last(inlineTokens).content = content.slice(0, curlyStart).trim();
}
inlineTokens[end].content = content.slice(0, curlyStart).trim();
}

@@ -114,1 +70,57 @@ }

};
/**
* test if inline token has proper formated curly end
*/
function hasCurlyEnd(token) {
// we need minimum four chars, example {.b}
if (!token.content || token.content.length < 4) {
return false;
}
// should end in }
var content = token.content;
if (content.charAt(content.length - 1) !== '}') {
return false;
}
// should start with {
var curlyStart = content.indexOf('{');
if (curlyStart === -1) {
return false;
}
return true;
}
/**
* some blocks are hidden (not rendered)
*/
function firstTokenNotHidden(tokens, i) {
if (tokens[i].hidden) {
return firstTokenNotHidden(tokens, i - 1);
}
return tokens[i];
}
/**
* find corresponding opening block
*/
function matchingOpeningToken(tokens, i) {
if (tokens[i].type === 'softbreak') {
return false;
}
// non closing blocks, example img
if (tokens[i].nesting === 0) {
return tokens[i];
}
var type = tokens[i].type.replace('_close', '_open');
for (; i >= 0; --i) {
if (tokens[i].type === type) {
return tokens[i];
}
}
}
function last(arr) {
return arr.slice(-1)[0];
}
{
"name": "markdown-it-attrs",
"version": "0.0.3",
"version": "0.1.0",
"description": "Add classes, identifiers and attributes to your markdown with {} curly brackets, similar to pandoc's header attributes",

@@ -18,3 +18,3 @@ "license": "MIT",

"prepublish": "mocha",
"postpublish": "git push; git push --tags"
"postpublish": "git tag $npm_package_version; git push --tags; git push"
},

@@ -21,0 +21,0 @@ "files": [

@@ -17,4 +17,31 @@ # 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)

Works with inline elements too:
```md
paragraph *style me*{.red} more text
```
Output:
```html
<p>paragraph <em class="red">style me</me> more text</p>
```
**Note:** Plugin does not validate any input, so you should validate the attributes in your html output if security is a concern.
## Ambiguity
When class can be applied to both inline or block element, inline element will take precedence:
```md
- list item **bold**{.red}
```
Output:
```html
<ul>
<li>list item <strong class="red">bold</strong></li>
<ul>
```
If you need finer control, look into [decorate](https://github.com/rstacruz/markdown-it-decorate).
## Install

@@ -21,0 +48,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc