unist-util-select
Advanced tools
Comparing version 0.1.0 to 1.0.0
'use strict'; | ||
var select = exports; | ||
select.selectors = function (selector, ast) { | ||
var result = []; | ||
selector.selectors.forEach(function (selector) { | ||
append(result, select.ruleSet(selector, ast)); | ||
}); | ||
return result; | ||
}; | ||
select.ruleSet = function (selector, ast) { | ||
@@ -35,3 +43,3 @@ return select.rule(selector.rule, ast); | ||
default: | ||
throw Error('Unexpected nesting operator: ' + selector.nestingOperator); | ||
throw Error('Undefined nesting operator: ' + selector.nestingOperator); | ||
} | ||
@@ -42,3 +50,3 @@ | ||
function walk (node, parent) { | ||
if (node.type == selector.tagName) { | ||
if (matches(selector, node)) { | ||
if (!selector.rule) { | ||
@@ -49,12 +57,14 @@ append(result, [node]); | ||
selector.rule.nestingOperator == '>') { | ||
if (!node.children) return; | ||
node.children.forEach(function (childNode) { | ||
[].push.apply(result, select.rule(selector.rule, childNode)); | ||
}); | ||
if (node.children) { | ||
node.children.forEach(function (childNode) { | ||
append(result, select.rule(selector.rule, childNode)); | ||
}); | ||
} | ||
} | ||
else { | ||
if (!parent) return; | ||
append(result, select.rule(selector.rule, { | ||
children: parent.children.slice(parent.children.indexOf(node) + 1) | ||
})); | ||
if (parent) { | ||
append(result, select.rule(selector.rule, { | ||
children: parent.children.slice(parent.children.indexOf(node) + 1) | ||
})); | ||
} | ||
} | ||
@@ -72,2 +82,51 @@ } | ||
// True if node matches head of selector rule. | ||
function matches (rule, node) { | ||
// Match type. | ||
if (rule.tagName && rule.tagName != '*' && node.type != rule.tagName) { | ||
return false; | ||
} | ||
// Match attributes. | ||
return (rule.attrs || []).every(function (attr) { | ||
switch (attr.operator) { | ||
case undefined: | ||
return attr.name in node; | ||
case '=': | ||
// First, check for special values. | ||
switch (attr.value) { | ||
case 'null': | ||
if (attr.name in node && node[attr.name] == null) return true; | ||
break; | ||
case 'true': | ||
if (node[attr.name] === true) return true; | ||
break; | ||
case 'false': | ||
if (node[attr.name] === false) return true; | ||
break; | ||
} | ||
return node[attr.name] == attr.value; | ||
case '^=': | ||
return typeof node[attr.name] == 'string' && | ||
node[attr.name].slice(0, attr.value.length) == attr.value; | ||
case '*=': | ||
return typeof node[attr.name] == 'string' && | ||
node[attr.name].indexOf(attr.value) >= 0; | ||
case '$=': | ||
return typeof node[attr.name] == 'string' && | ||
node[attr.name].slice(-attr.value.length) == attr.value; | ||
default: | ||
throw Error('Undefined attribute operator: ' + attr.operator); | ||
} | ||
}); | ||
} | ||
function append (array, elements) { | ||
@@ -74,0 +133,0 @@ elements.forEach(function (el) { |
@@ -9,3 +9,4 @@ 'use strict'; | ||
parser.registerNestingOperators('>', '+', '~'); | ||
parser.registerAttrEqualityMods('^', '*', '$'); | ||
return parser.parse.bind(parser); | ||
}; |
{ | ||
"name": "unist-util-select", | ||
"version": "0.1.0", | ||
"version": "1.0.0", | ||
"description": "Select unist nodes using css-like selectors", | ||
@@ -24,3 +24,8 @@ "author": "Eugene Sharygin <eush77@gmail.com>", | ||
"type", | ||
"attribute", | ||
"expression", | ||
"filter", | ||
"find", | ||
"match", | ||
"ast", | ||
"mdast", | ||
@@ -27,0 +32,0 @@ "node", |
@@ -16,9 +16,33 @@ [![npm](https://nodei.co/npm/unist-util-select.png)](https://npmjs.com/package/unist-util-select) | ||
`example.md`: | ||
``` | ||
Get all TODO items from this list: | ||
1. Step 1. | ||
2. TODO Step 2. | ||
3. Step 3. | ||
1. TODO Step 3.1. | ||
2. Step 3.2. | ||
3. TODO Step 3.3. | ||
``` | ||
[`mdast`][mdast] takes this Markdown as an input and returns unist syntax tree. After that, we use `unist-util-select` to extract the required parts: | ||
```js | ||
var select = require('unist-util-select'); | ||
select(ast, 'paragraph emphasis > text') | ||
//=> array of nodes | ||
var markdown = fs.readFileSync('example.md', 'utf8'); | ||
var ast = mdast.parse(markdown); | ||
select(ast, 'list text[value*=TODO]') | ||
//=> [ { type: 'text', value: 'TODO Step 2.' }, | ||
// { type: 'text', value: 'TODO Step 3.1.' }, | ||
// { type: 'text', value: 'TODO Step 3.3.' } ] | ||
``` | ||
That's it! | ||
[mdast]: https://github.com/wooorm/mdast | ||
## Features | ||
@@ -31,9 +55,14 @@ | ||
- [x] Adjacent sibling selectors: `paragraph + text` | ||
- [ ] Attribute selectors: `text[value*="substr"]` | ||
- [ ] Universal selectors: `*` | ||
- [ ] Group selectors: `paragraph, text` | ||
- [x] Group selectors: `paragraph, text` | ||
- [x] Universal selector: `*` | ||
- [x] Attribute selectors: `text[value*="substr"]` | ||
- [x] Existence: `[value]` | ||
- [x] Equality: `[value="foo"]` | ||
- [x] Begins with: `[value^="prefix"]` | ||
- [x] Containment: `[value*="substr"]` | ||
- [x] Ends with: `[value$="suffix"]` | ||
## API | ||
#### `unistUtilSelect(ast, selector)` | ||
#### `select(ast, selector)` | ||
@@ -40,0 +69,0 @@ Applies `selector` to `ast`, returns array of matching nodes. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
7528
123
0
78