visualwidth
Advanced tools
Comparing version 0.0.1 to 0.1.0
{ | ||
"name": "visualwidth", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"description": "unicode character visual width", | ||
@@ -10,3 +10,3 @@ "main": "visualwidth.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "node ./t/test.js" | ||
}, | ||
@@ -22,3 +22,6 @@ "repository": { | ||
"author": "Tokuhiro Matsuno <tokuhirom@gmail.com>", | ||
"license": "MIT" | ||
"license": "MIT", | ||
"devDependencies": { | ||
"tape": "^3.0.3" | ||
} | ||
} |
@@ -1,30 +0,58 @@ | ||
subtest('width', function () { | ||
is(width('ใใใใใ'), 10); | ||
is(width('...'), 3); | ||
is(width('Shinjuku'), 8); | ||
is(width('โฆ'), 2); | ||
is(width("\u2026"), 2); // ambiguous char should be full width | ||
var test =require('tape'); | ||
var vw = require('../'); | ||
test('vw.width', function (t) { | ||
t.equals(vw.width('ใใใใใ'), 10); | ||
t.equals(vw.width('...'), 3); | ||
t.equals(vw.width('Shinjuku'), 8); | ||
t.equals(vw.width('โฆ'), 2); | ||
t.equals(vw.width("\u2026"), 2); // ambiguous char should be full width | ||
t.end(); | ||
}); | ||
subtest('width/surrogate pair', function () { | ||
is(width(String.fromCharCode(0xD800, 0xDC00)), 1); // U+10000 LINEAR B SYLLABLE B008 A (first non-BMP code point) ( half width ) | ||
is(width(String.fromCharCode(0xD840, 0xDC0B)), 2); | ||
is(width(String.fromCharCode(0xD869, 0xDEB2)), 2); | ||
is(width(String.fromCharCode(0xD840, 0xDC0B) + String.fromCharCode(0xD869, 0xDEB2)), 4); | ||
test('vw short for vw.width', function (t) { | ||
t.equals(vw.width('ใใใใใ'), 10); | ||
t.end(); | ||
}) | ||
test('vw.width/surrogate pair', function (t) { | ||
t.equals(vw.width(String.fromCharCode(0xD800, 0xDC00)), 1); // U+10000 LINEAR B SYLLABLE B008 A (first non-BMP code point) ( half width ) | ||
t.equals(vw.width(String.fromCharCode(0xD840, 0xDC0B)), 2); | ||
t.equals(vw.width(String.fromCharCode(0xD869, 0xDEB2)), 2); | ||
t.equals(vw.width(String.fromCharCode(0xD840, 0xDC0B) + String.fromCharCode(0xD869, 0xDEB2)), 4); | ||
t.end(); | ||
}); | ||
subtest('truncate', function () { | ||
is(truncate('DOUTOR ๆฐๅฎฟใขใคใฉใณใๅบ', 15, '...'), 'DOUTOR ๆฐๅฎฟ...'); | ||
is(truncate('็กๅฐ่ฏๅ ใขใญใใปใใชใ ', 20, '...'), '็กๅฐ่ฏๅ ใขใญใใป...'); | ||
is(truncate('VILLAGE VANGUARD ๆธ่ฐทๅฎ็ฐๅท', 15, '...'), 'VILLAGE VANG...'); | ||
is(truncate('VILLAGE VANGUARD ๆธ่ฐทๅฎ็ฐๅท', 15, '...').length, 15); | ||
is(truncate('Shinjuku', 15, 'โฆ'), 'Shinjuku'); | ||
is(truncate('ใใใใใ', 12, '...'), 'ใใใใใ'); | ||
is(truncate('ใใใใใ', 11, '...'), 'ใใใใใ'); | ||
is(truncate('ใใใใใ', 10, '...'), 'ใใใใใ'); | ||
is(truncate('ใใใใใ', 9, '...'), 'ใใใ...'); | ||
is(truncate('ใใใใใ', 8, '...'), 'ใใ...'); | ||
is(truncate('ใใใใใ', 7, '...'), 'ใใ...'); | ||
is(truncate('ใใใใใ', 6, '...'), 'ใ...'); | ||
is(truncate('ใใใใใ', 5, '...'), 'ใ...'); | ||
test('truncate', function (t) { | ||
t.equals(vw.truncate('DOUTOR ๆฐๅฎฟใขใคใฉใณใๅบ', 15, '...'), 'DOUTOR ๆฐๅฎฟ...'); | ||
t.equals(vw.truncate('็กๅฐ่ฏๅ ใขใญใใปใใชใ ', 20, '...'), '็กๅฐ่ฏๅ ใขใญใใป...'); | ||
t.equals(vw.truncate('VILLAGE VANGUARD ๆธ่ฐทๅฎ็ฐๅท', 15, '...'), 'VILLAGE VANG...'); | ||
t.equals(vw.truncate('VILLAGE VANGUARD ๆธ่ฐทๅฎ็ฐๅท', 15, '...').length, 15); | ||
t.equals(vw.truncate('Shinjuku', 15, 'โฆ'), 'Shinjuku'); | ||
t.equals(vw.truncate('ใใใใใ', 12, '...'), 'ใใใใใ'); | ||
t.equals(vw.truncate('ใใใใใ', 11, '...'), 'ใใใใใ'); | ||
t.equals(vw.truncate('ใใใใใ', 10, '...'), 'ใใใใใ'); | ||
t.equals(vw.truncate('ใใใใใ', 9, '...'), 'ใใใ...'); | ||
t.equals(vw.truncate('ใใใใใ', 8, '...'), 'ใใ...'); | ||
t.equals(vw.truncate('ใใใใใ', 7, '...'), 'ใใ...'); | ||
t.equals(vw.truncate('ใใใใใ', 6, '...'), 'ใ...'); | ||
t.equals(vw.truncate('ใใใใใ', 5, '...'), 'ใ...'); | ||
t.end(); | ||
}); | ||
test('terminal characters', function (t) { | ||
t.equals(vw.width('\x1B[0mH', true), 1); | ||
t.equals(vw.width('\x1B[0mH'), 5); | ||
t.equals(vw.width('\x1B[31mH\x1B[0m', true), 1); | ||
t.equals(vw.width('\x1B[31mใ\x1B[0m', true), 2); | ||
t.equals(vw.width('\x1B[31mใ\x1B[0mB', true), 3); | ||
t.end(); | ||
}); | ||
test('truncate terminal characters', function (t) { | ||
t.equals(vw.truncate('\x1B[31mHello World', 10, '...', true), '\x1B[31mHello W...'); | ||
t.equals(vw.truncate('\x1B[31mHello World\x1B[0m', 10, '...', true), '\x1B[31mHello W...'); | ||
t.equals(vw.truncate('\x1B[31mHello World', 10, '\x1B[0m...', true), '\x1B[31mHello W\x1B[0m...'); | ||
t.equals(vw.truncate('็งใฎ\x1B[31mใขใณในใฟใผ\x1B[0mใใณใฟใผ', 12, '\x1B[0mโฆ', true), '็งใฎ\x1b[31mใขใณใน\x1b[0mโฆ'); | ||
t.end(); | ||
}); |
@@ -9,5 +9,5 @@ // http://tokuhirom.mit-license.org | ||
if (typeof exports !== 'undefined') { | ||
VisualWidth = exports; | ||
module.exports = VisualWidth = width; | ||
} else { | ||
global.VisualWidth = VisualWidth = {}; | ||
global.VisualWidth = VisualWidth = width; | ||
} | ||
@@ -17,6 +17,10 @@ VisualWidth.truncate = truncate; | ||
function width(string) { | ||
function width(string, terminal) { | ||
var counter=0, | ||
i, l, c, cp; | ||
if (terminal) { | ||
string = string.replace(/\x1B\[[0-9;]*m/g, '') | ||
} | ||
for (i=0, l=string.length; i<l; i++) { | ||
@@ -50,22 +54,38 @@ c = string.charCodeAt(i); | ||
function truncate(string, length, suffix) { | ||
function truncate(string, length, suffix, terminal) { | ||
var ret = '', | ||
c, clen, | ||
counter=0, | ||
chars = string.split(''), | ||
chars, | ||
i, l, | ||
slen = width(suffix); | ||
max, | ||
terminalBlock; | ||
if (width(string) <= length) { | ||
if (width(string, terminal) <= length) { | ||
return string; | ||
} | ||
chars = string.split('') | ||
max = length - width(suffix, terminal) | ||
for (i=0, l=chars.length; i<l && counter < length; i++) { | ||
c = chars[i]; | ||
clen = width(c); | ||
if (counter + clen + slen > length) { | ||
if (terminalBlock) { | ||
if (c === "m") { | ||
terminalBlock = false | ||
} | ||
ret += c; | ||
continue; | ||
} | ||
if (c === "\x1B") { | ||
terminalBlock = true; | ||
ret += c; | ||
continue; | ||
} | ||
clen = width(c, terminal); | ||
counter += clen; | ||
if (counter > max) { | ||
return ret + suffix; | ||
} | ||
ret += c; | ||
counter += clen; | ||
} | ||
@@ -72,0 +92,0 @@ return ret; // maybe fatal |
Sorry, the diff of this file is not supported yet
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
2
16
0
0
12330
1
8
148
2