nlcst-emoji-modifier
Advanced tools
Comparing version 4.1.1 to 5.0.0
184
index.js
@@ -1,19 +0,31 @@ | ||
'use strict' | ||
/** | ||
* @typedef {import('unist').Node} Node | ||
* @typedef {import('unist').Parent} Parent | ||
* @typedef {import('unist').Point} Point | ||
* | ||
* @typedef {Object} FindMatch | ||
* @property {number} start | ||
* @property {number} end | ||
* | ||
* @typedef {Object} ChangeResult | ||
* @property {Array.<Node>} nodes | ||
* @property {number} end | ||
*/ | ||
var visit = require('unist-util-visit') | ||
var position = require('unist-util-position') | ||
var generated = require('unist-util-generated') | ||
var toString = require('nlcst-to-string') | ||
var gemojiNameToEmoji = require('gemoji/name-to-emoji') | ||
var emojiRegex = require('emoji-regex') | ||
import {visit} from 'unist-util-visit' | ||
import {position, pointStart, pointEnd} from 'unist-util-position' | ||
import {generated} from 'unist-util-generated' | ||
import {toString} from 'nlcst-to-string' | ||
import {nameToEmoji} from 'gemoji' | ||
import emojiRegex from 'emoji-regex' | ||
module.exports = mergeEmoji | ||
var own = {}.hasOwnProperty | ||
var colon = ':' | ||
var push = [].push | ||
var vs16 = 0xfe0f | ||
// Merge emoji (π) and Gemoji (GitHub emoji, :+1:). | ||
function mergeEmoji(node) { | ||
/** | ||
* Merge emoji (π) and Gemoji (GitHub emoji, :+1:). | ||
* | ||
* @param {Parent} node | ||
*/ | ||
export function emojiModifier(node) { | ||
if (!node || !node.children) { | ||
@@ -23,7 +35,4 @@ throw new Error('Missing children in `parent`') | ||
var matches = findEmoji(node) | ||
var result = changeParent(node, matches, 0) | ||
node.children = changeParent(node, findEmoji(node), 0).nodes | ||
node.children = result.nodes | ||
visit(node, 'EmoticonNode', removeMatch) | ||
@@ -34,24 +43,28 @@ | ||
/** | ||
* @param {Parent} node | ||
* @param {Array.<FindMatch>} matches | ||
* @param {number} start | ||
*/ | ||
function changeParent(node, matches, start) { | ||
var children = node.children | ||
var length = children.length | ||
var end = start | ||
var index = -1 | ||
/** @type {Array.<Node>} */ | ||
var nodes = [] | ||
/** @type {Array.<Node>} */ | ||
var merged = [] | ||
/** @type {ChangeResult} */ | ||
var result | ||
/** @type {Node} */ | ||
var child | ||
var merged | ||
/** @type {Node} */ | ||
var previous | ||
var parent | ||
while (++index < length) { | ||
child = children[index] | ||
if (child.children) { | ||
result = changeParent(child, matches, end) | ||
} else { | ||
result = changeLeaf(child, matches, end) | ||
} | ||
nodes = nodes.concat(result.nodes) | ||
while (++index < children.length) { | ||
result = children[index].children | ||
? // @ts-ignore Looks like a parent. | ||
changeParent(children[index], matches, end) | ||
: changeLeaf(children[index], matches, end) | ||
push.apply(nodes, result.nodes) | ||
end = result.end | ||
@@ -61,18 +74,15 @@ } | ||
index = -1 | ||
length = nodes.length | ||
merged = [] | ||
while (++index < length) { | ||
child = nodes[index] | ||
while (++index < nodes.length) { | ||
if (nodes[index].type === 'EmoticonNode') { | ||
if (previous && previous._match === nodes[index]._match) { | ||
// @ts-ignore Both literals. | ||
previous.value += nodes[index].value | ||
if (child.type === 'EmoticonNode') { | ||
if (previous && previous.match === child.match) { | ||
previous.value += child.value | ||
if (!generated(previous)) { | ||
previous.position.end = position.end(child) | ||
previous.position.end = pointEnd(nodes[index]) | ||
} | ||
} else { | ||
previous = child | ||
merged.push(child) | ||
previous = nodes[index] | ||
merged.push(nodes[index]) | ||
} | ||
@@ -83,14 +93,11 @@ } else { | ||
if (node.type === 'WordNode') { | ||
parent = {type: node.type, children: [child]} | ||
child = {type: node.type, children: [nodes[index]]} | ||
if (!generated(child)) { | ||
parent.position = { | ||
start: position.start(child), | ||
end: position.end(child) | ||
} | ||
if (!generated(nodes[index])) { | ||
child.position = position(nodes[index]) | ||
} | ||
merged.push(parent) | ||
merged.push(child) | ||
} else { | ||
merged.push(child) | ||
merged.push(nodes[index]) | ||
} | ||
@@ -100,26 +107,36 @@ } | ||
return {end: end, nodes: merged} | ||
return {end, nodes: merged} | ||
} | ||
/** | ||
* @param {Node} node | ||
* @param {Array.<FindMatch>} matches | ||
* @param {number} start | ||
* @returns {ChangeResult} | ||
*/ | ||
function changeLeaf(node, matches, start) { | ||
var value = toString(node) | ||
var point = generated(node) ? null : position.start(node) | ||
var point = generated(node) ? null : pointStart(node) | ||
var end = start + value.length | ||
var length = matches.length | ||
var index = -1 | ||
var textEnd = 0 | ||
/** @type {Array.<Node>} */ | ||
var nodes = [] | ||
var emojiBegin | ||
/** @type {number} */ | ||
var emojiEnd | ||
/** @type {Node} */ | ||
var child | ||
/** @type {FindMatch} */ | ||
var match | ||
while (++index < length) { | ||
while (++index < matches.length) { | ||
match = matches[index] | ||
emojiBegin = match.start - start | ||
emojiEnd = match.end - start + 1 | ||
if (emojiBegin < value.length && emojiEnd > 0) { | ||
if (emojiBegin > textEnd) { | ||
child = {type: node.type, value: value.slice(textEnd, emojiBegin)} | ||
if (match.start - start < value.length && emojiEnd > 0) { | ||
if (match.start - start > textEnd) { | ||
child = { | ||
type: node.type, | ||
value: value.slice(textEnd, match.start - start) | ||
} | ||
@@ -129,3 +146,3 @@ if (point) { | ||
start: shift(point, textEnd), | ||
end: shift(point, emojiBegin) | ||
end: shift(point, match.start - start) | ||
} | ||
@@ -135,3 +152,3 @@ } | ||
nodes.push(child) | ||
textEnd = emojiBegin | ||
textEnd = match.start - start | ||
} | ||
@@ -146,3 +163,3 @@ | ||
value: value.slice(textEnd, emojiEnd), | ||
match: match | ||
_match: match | ||
} | ||
@@ -158,3 +175,2 @@ | ||
nodes.push(child) | ||
textEnd = emojiEnd | ||
@@ -174,11 +190,18 @@ } | ||
return {end: end, nodes: nodes} | ||
return {end, nodes} | ||
} | ||
/** | ||
* @param {Node} node | ||
*/ | ||
function findEmoji(node) { | ||
var emojiExpression = emojiRegex() | ||
/** @type {Array.<FindMatch>} */ | ||
var matches = [] | ||
var value = toString(node) | ||
var start = value.indexOf(colon) | ||
var end = start === -1 ? -1 : value.indexOf(colon, start + 1) | ||
var start = value.indexOf(':') | ||
var end = start === -1 ? -1 : value.indexOf(':', start + 1) | ||
/** @type {string} */ | ||
var slice | ||
/** @type {RegExpExecArray} */ | ||
var match | ||
@@ -188,7 +211,7 @@ | ||
while (end !== -1) { | ||
match = value.slice(start + 1, end) | ||
slice = value.slice(start + 1, end) | ||
if (own.call(gemojiNameToEmoji, match)) { | ||
matches.push({start: start, end: end}) | ||
start = value.indexOf(colon, end + 1) | ||
if (own.call(nameToEmoji, slice)) { | ||
matches.push({start, end}) | ||
start = value.indexOf(':', end + 1) | ||
} else { | ||
@@ -198,3 +221,3 @@ start = end | ||
end = start === -1 ? -1 : value.indexOf(colon, start + 1) | ||
end = start === -1 ? -1 : value.indexOf(':', start + 1) | ||
} | ||
@@ -207,7 +230,7 @@ | ||
if (value.charCodeAt(end + 1) === vs16) { | ||
if (value.charCodeAt(end + 1) === 0xfe0f) { | ||
end++ | ||
} | ||
matches.push({start: start, end: end}) | ||
matches.push({start, end}) | ||
} | ||
@@ -220,6 +243,14 @@ | ||
/** | ||
* @param {Node} node | ||
*/ | ||
function removeMatch(node) { | ||
delete node.match | ||
delete node._match | ||
} | ||
/** | ||
* @param {FindMatch} a | ||
* @param {FindMatch} b | ||
* @returns {number} | ||
*/ | ||
function sort(a, b) { | ||
@@ -229,2 +260,7 @@ return a.start - b.start | ||
/** | ||
* @param {Point} point | ||
* @param {number} offset | ||
* @returns {Point} | ||
*/ | ||
function shift(point, offset) { | ||
@@ -231,0 +267,0 @@ return { |
{ | ||
"name": "nlcst-emoji-modifier", | ||
"version": "4.1.1", | ||
"version": "5.0.0", | ||
"description": "nlcst utility to support emoji", | ||
@@ -26,4 +26,8 @@ "license": "MIT", | ||
], | ||
"sideEffects": false, | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"files": [ | ||
"data/emoji.json", | ||
"index.d.ts", | ||
"index.js" | ||
@@ -33,38 +37,32 @@ ], | ||
"emoji-regex": "^9.0.0", | ||
"gemoji": "^6.0.0", | ||
"nlcst-to-string": "^2.0.0", | ||
"unist-util-generated": "^1.0.0", | ||
"unist-util-position": "^3.0.0", | ||
"unist-util-visit": "^2.0.0" | ||
"gemoji": "^7.0.0", | ||
"nlcst-to-string": "^3.0.0", | ||
"unist-util-generated": "^2.0.0", | ||
"unist-util-position": "^4.0.0", | ||
"unist-util-visit": "^3.0.0" | ||
}, | ||
"devDependencies": { | ||
"browserify": "^16.0.0", | ||
"is-hidden": "^1.0.0", | ||
"negate": "^1.0.0", | ||
"nyc": "^15.0.0", | ||
"parse-english": "^4.0.0", | ||
"@types/tape": "^4.0.0", | ||
"c8": "^7.0.0", | ||
"is-hidden": "^2.0.0", | ||
"parse-english": "^5.0.0", | ||
"prettier": "^2.0.0", | ||
"remark-cli": "^8.0.0", | ||
"remark-preset-wooorm": "^7.0.0", | ||
"remark-cli": "^9.0.0", | ||
"remark-preset-wooorm": "^8.0.0", | ||
"rimraf": "^3.0.0", | ||
"tape": "^5.0.0", | ||
"tinyify": "^3.0.0", | ||
"unist-builder": "^2.0.0", | ||
"unist-util-remove-position": "^3.0.0", | ||
"xo": "^0.33.0" | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"unist-builder": "^3.0.0", | ||
"unist-util-remove-position": "^4.0.0", | ||
"xo": "^0.38.0" | ||
}, | ||
"scripts": { | ||
"format": "remark . -qfo && prettier . --write && xo --fix", | ||
"build-bundle": "browserify . -s nlcstEmojiModifier > nlcst-emoji-modifier.js", | ||
"build-mangle": "browserify . -s nlcstEmojiModifier -p tinyify -o nlcst-emoji-modifier.min.js", | ||
"build": "npm run build-bundle && npm run build-mangle", | ||
"test-api": "node test", | ||
"test-coverage": "nyc --reporter lcov tape test/index.js", | ||
"test": "npm run format && npm run build && npm run test-coverage" | ||
"prepack": "npm run build && npm run format", | ||
"build": "rimraf \"{test/**,}*.d.ts\" && tsc && type-coverage", | ||
"format": "remark . -qfo && prettier . --write --loglevel warn && xo --fix", | ||
"test-api": "node test/index.js", | ||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test/index.js", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
}, | ||
"nyc": { | ||
"check-coverage": true, | ||
"lines": 100, | ||
"functions": 100, | ||
"branches": 100 | ||
}, | ||
"prettier": { | ||
@@ -80,11 +78,7 @@ "tabWidth": 2, | ||
"prettier": true, | ||
"esnext": false, | ||
"rules": { | ||
"unicorn/no-fn-reference-in-iterator": "off", | ||
"guard-for-in": "off", | ||
"complexity": "off" | ||
}, | ||
"ignore": [ | ||
"nlcst-emoji-modifier.js" | ||
] | ||
"unicorn/no-array-for-each": "off", | ||
"no-var": "off", | ||
"prefer-arrow-callback": "off" | ||
} | ||
}, | ||
@@ -95,3 +89,8 @@ "remarkConfig": { | ||
] | ||
}, | ||
"typeCoverage": { | ||
"atLeast": 100, | ||
"detail": true, | ||
"strict": true | ||
} | ||
} |
@@ -18,2 +18,5 @@ # nlcst-emoji-modifier | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): | ||
Node 12+ is needed to use it and it must be `import`ed instead of `require`d. | ||
[npm][]: | ||
@@ -28,7 +31,8 @@ | ||
```js | ||
var modifier = require('nlcst-emoji-modifier') | ||
var inspect = require('unist-util-inspect') | ||
var english = require('parse-english')() | ||
import {emojiModifier} from 'nlcst-emoji-modifier' | ||
import {inspect} from 'unist-util-inspect' | ||
import {ParseEnglish} from 'parse-english' | ||
english.useFirst('tokenizeSentence', modifier) | ||
var english = new ParseEnglish() | ||
english.useFirst('tokenizeSentence', emojiModifier) | ||
@@ -67,4 +71,7 @@ console.log(inspect(english.parse('Itβs raining :cat:s and :dog:s.'))) | ||
### `emoji(node)` | ||
This package exports the following identifiers: `emojiModifier`. | ||
There is no default export. | ||
### `emojiModifier(node)` | ||
Merge emoji and gemoji into a new `EmoticonNode`. | ||
@@ -99,5 +106,5 @@ | ||
[build-badge]: https://img.shields.io/travis/syntax-tree/nlcst-emoji-modifier.svg | ||
[build-badge]: https://github.com/syntax-tree/nlcst-emoji-modifier/workflows/main/badge.svg | ||
[build]: https://travis-ci.org/syntax-tree/nlcst-emoji-modifier | ||
[build]: https://github.com/syntax-tree/nlcst-emoji-modifier/actions | ||
@@ -104,0 +111,0 @@ [coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/nlcst-emoji-modifier.svg |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
13860
5
234
146
Yes
14
1
+ Added@types/nlcst@1.0.4(transitive)
+ Addedgemoji@7.1.0(transitive)
+ Addednlcst-to-string@3.1.1(transitive)
+ Addedunist-util-generated@2.0.1(transitive)
+ Addedunist-util-is@5.2.1(transitive)
+ Addedunist-util-position@4.0.4(transitive)
+ Addedunist-util-visit@3.1.0(transitive)
+ Addedunist-util-visit-parents@4.1.1(transitive)
- Removedgemoji@6.1.0(transitive)
- Removednlcst-to-string@2.0.4(transitive)
- Removedunist-util-generated@1.1.6(transitive)
- Removedunist-util-is@4.1.0(transitive)
- Removedunist-util-position@3.1.0(transitive)
- Removedunist-util-visit@2.0.3(transitive)
- Removedunist-util-visit-parents@3.1.1(transitive)
Updatedgemoji@^7.0.0
Updatednlcst-to-string@^3.0.0
Updatedunist-util-generated@^2.0.0
Updatedunist-util-position@^4.0.0
Updatedunist-util-visit@^3.0.0