diff --git a/package.json b/package.json index f0c908d..7c01f8b 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "docs": "d3plus-docs", "env": "d3plus-env", "release": "d3plus-release", - "test": "eslint src test && mocha 'test/**/*-test.js'" + "test": "eslint src test && mocha 'test/**/*-test.js'", + "prepare": "yarn build" }, "devDependencies": { "d3plus-dev": "^1.2.9" diff --git a/src/textWrap.js b/src/textWrap.js index 81eaf77..0dcf785 100644 --- a/src/textWrap.js +++ b/src/textWrap.js @@ -1,30 +1,28 @@ -import measure from "./textWidth.js"; -import defaultSplit from "./textSplit.js"; -import stringify from "./stringify.js"; -import {trimRight} from "./trim.js"; +import measure from './textWidth.js'; +import defaultSplit from './textSplit.js'; +import stringify from './stringify.js'; +import { trimRight } from './trim.js'; /** @function textWrap @desc Based on the defined styles and dimensions, breaks a string into an array of strings for each line of text. */ -export default function() { - - let fontFamily = "sans-serif", - fontSize = 10, - fontWeight = 400, - height = 200, - lineHeight, - maxLines = null, - overflow = false, - split = defaultSplit, - width = 200; +export default function () { + let fontFamily = 'sans-serif', + fontSize = 10, + fontWeight = 400, + height = 200, + lineHeight, + maxLines = null, + overflow = false, + split = defaultSplit, + width = 200; /** The inner return object and wraps the text and returns the line data array. @private */ function textWrap(sentence) { - sentence = stringify(sentence); if (lineHeight === void 0) lineHeight = Math.ceil(fontSize * 1.4); @@ -32,53 +30,65 @@ export default function() { const words = split(sentence); const style = { - "font-family": fontFamily, - "font-size": fontSize, - "font-weight": fontWeight, - "line-height": lineHeight + 'font-family': fontFamily, + 'font-size': fontSize, + 'font-weight': fontWeight, + 'line-height': lineHeight, }; let line = 1, - textProg = "", - truncated = false, - widthProg = 0; + textProg = '', + truncated = false, + widthProg = 0; const lineData = [], - sizes = measure(words, style), - space = measure(" ", style); + sizes = measure(words, style), + space = measure(' ', style); for (let i = 0; i < words.length; i++) { let word = words[i]; const wordWidth = sizes[words.indexOf(word)]; - word += sentence.slice(textProg.length + word.length).match("^( |\n)*", "g")[0]; - if (textProg.slice(-1) === "\n" || widthProg + wordWidth > width) { - if (!i && !overflow) { - truncated = true; - break; + word += sentence + .slice(textProg.length + word.length) + .match('^( |\n)*', 'g')[0]; + + if ( + i === 0 || + textProg.slice(-1) === '\n' || + widthProg + wordWidth > width + ) { + if (i > 0) { + if (lineData.length >= line) { + lineData[line - 1] = trimRight(lineData[line - 1]); + } + line++; } - if (lineData.length >= line) lineData[line - 1] = trimRight(lineData[line - 1]); - line++; - if (lineHeight * line > height || wordWidth > width && !overflow || maxLines && line > maxLines) { + + if (lineHeight * line > height || (maxLines && line > maxLines)) { truncated = true; break; } - widthProg = 0; + + widthProg = wordWidth; + lineData.push(word); + } else { + lineData[line - 1] += word; + widthProg += wordWidth; } - else if (!i) lineData[0] = word; - else lineData[line - 1] += word; + textProg += word; - widthProg += wordWidth; widthProg += word.match(/[\s]*$/g)[0].length * space; + console.log('\n'); } return { lines: lineData, - sentence, truncated, + sentence, + truncated, widths: measure(lineData, style), - words + words, }; - } /** @@ -86,8 +96,8 @@ export default function() { @desc If *value* is specified, sets the font family accessor to the specified function or string and returns this generator. If *value* is not specified, returns the current font family. @param {Function|String} [*value* = "sans-serif"] */ - textWrap.fontFamily = function(_) { - return arguments.length ? (fontFamily = _, textWrap) : fontFamily; + textWrap.fontFamily = function (_) { + return arguments.length ? ((fontFamily = _), textWrap) : fontFamily; }; /** @@ -95,8 +105,8 @@ export default function() { @desc If *value* is specified, sets the font size accessor to the specified function or number and returns this generator. If *value* is not specified, returns the current font size. @param {Function|Number} [*value* = 10] */ - textWrap.fontSize = function(_) { - return arguments.length ? (fontSize = _, textWrap) : fontSize; + textWrap.fontSize = function (_) { + return arguments.length ? ((fontSize = _), textWrap) : fontSize; }; /** @@ -104,8 +114,8 @@ export default function() { @desc If *value* is specified, sets the font weight accessor to the specified function or number and returns this generator. If *value* is not specified, returns the current font weight. @param {Function|Number|String} [*value* = 400] */ - textWrap.fontWeight = function(_) { - return arguments.length ? (fontWeight = _, textWrap) : fontWeight; + textWrap.fontWeight = function (_) { + return arguments.length ? ((fontWeight = _), textWrap) : fontWeight; }; /** @@ -113,8 +123,8 @@ export default function() { @desc If *value* is specified, sets height limit to the specified value and returns this generator. If *value* is not specified, returns the current value. @param {Number} [*value* = 200] */ - textWrap.height = function(_) { - return arguments.length ? (height = _, textWrap) : height; + textWrap.height = function (_) { + return arguments.length ? ((height = _), textWrap) : height; }; /** @@ -122,8 +132,8 @@ export default function() { @desc If *value* is specified, sets the line height accessor to the specified function or number and returns this generator. If *value* is not specified, returns the current line height accessor, which is 1.1 times the [font size](#textWrap.fontSize) by default. @param {Function|Number} [*value*] */ - textWrap.lineHeight = function(_) { - return arguments.length ? (lineHeight = _, textWrap) : lineHeight; + textWrap.lineHeight = function (_) { + return arguments.length ? ((lineHeight = _), textWrap) : lineHeight; }; /** @@ -131,8 +141,8 @@ export default function() { @desc If *value* is specified, sets the maximum number of lines allowed when wrapping. @param {Function|Number} [*value*] */ - textWrap.maxLines = function(_) { - return arguments.length ? (maxLines = _, textWrap) : maxLines; + textWrap.maxLines = function (_) { + return arguments.length ? ((maxLines = _), textWrap) : maxLines; }; /** @@ -140,8 +150,8 @@ export default function() { @desc If *value* is specified, sets the overflow to the specified boolean and returns this generator. If *value* is not specified, returns the current overflow value. @param {Boolean} [*value* = false] */ - textWrap.overflow = function(_) { - return arguments.length ? (overflow = _, textWrap) : overflow; + textWrap.overflow = function (_) { + return arguments.length ? ((overflow = _), textWrap) : overflow; }; /** @@ -149,8 +159,8 @@ export default function() { @desc If *value* is specified, sets the word split function to the specified function and returns this generator. If *value* is not specified, returns the current word split function. @param {Function} [*value*] A function that, when passed a string, is expected to return that string split into an array of words to textWrap. The default split function splits strings on the following characters: `-`, `/`, `;`, `:`, `&` */ - textWrap.split = function(_) { - return arguments.length ? (split = _, textWrap) : split; + textWrap.split = function (_) { + return arguments.length ? ((split = _), textWrap) : split; }; /** @@ -158,10 +168,9 @@ export default function() { @desc If *value* is specified, sets width limit to the specified value and returns this generator. If *value* is not specified, returns the current value. @param {Number} [*value* = 200] */ - textWrap.width = function(_) { - return arguments.length ? (width = _, textWrap) : width; + textWrap.width = function (_) { + return arguments.length ? ((width = _), textWrap) : width; }; return textWrap; - }