Skip to content

Commit

Permalink
'Wrap' value addition for issue #52
Browse files Browse the repository at this point in the history
Allow user to specify 'wrap' option as true or false values, with true representing 'auto' matic wrapping and false representing 'ellipsis' line truncation marking.
  • Loading branch information
shaehn committed Nov 5, 2019
1 parent 6bdc36b commit f0449db
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 10 deletions.
55 changes: 48 additions & 7 deletions docs/text.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ <h1 class="page-title">text.js</h1>
* @param {number} [options.textBox.minHeight=0] - Text Box minimum height
* @param {number|number[]} [options.textBox.padding=0] - Text Box padding, [top, right, bottom, left]
* @param {number} [options.textBox.lineHeight=0] - Text Box line height
* @param {string} [options.textBox.wrap='auto'] - Text wrapping mechanism, 'auto', 'clip', 'trim'.
* @param {string|Boolean} [options.textBox.wrap='auto'] - Text wrapping mechanism, may be true, false,
* 'auto', 'clip', 'trim', 'ellipsis'. All the option values that are not equivalent to 'auto' dictate
* how the text which does not fit on a line is to be truncated. True is equivalent to 'auto'. False is equivalent to 'ellipsis'.
* @param {string} [options.textBox.textAlign='left top'] - Alignment inside text box, specified as 'horizontal vertical',
* where horizontal is one of: 'left', 'center', 'right', 'justify' and veritical is one of: 'top', 'center', 'bottom'.
* @param {Object} [options.textBox.style] - Text Box styles
Expand Down Expand Up @@ -140,6 +142,13 @@ <h1 class="page-title">text.js</h1>
wrap: (options.textBox.wrap !== undefined) ? options.textBox.wrap : 'auto'
};

// allow user to treat wrap as boolean
if (textBox.wrap === true) {
textBox.wrap = 'auto';
} else if (textBox.wrap === false) {
textBox.wrap = 'ellipsis'
}

// Allows user to enter a single number which will be used for all text box sides,
// or an array of values [top, right, bottom, left] with any combination of missing sides.
// Default value for a missing side is the value of the text box's opposite side (see below).
Expand Down Expand Up @@ -480,6 +489,39 @@ <h1 class="page-title">text.js</h1>
return new Word(nextWord, pathOptions);
}

function elideNonFittingText(textBox, line, word, pathOptions) {
if (textBox.wrap === 'clip') {
line.addWord(word);
} else if (textBox.wrap === 'ellipsis') {
// This is more complicated than the other no-wrap options.
// It makes an initial attempt to take the word that was
// too big and make it shrink in size until it and the
// ellipsis character fit. If that doesn't work, one more
// stab is taken by trying to shrink the previous word
// that fit on the line.
const ellipsis = '…';
let usingPreviousWord = false;
let tooBig = new Word(word.value.slice(0,-2)+ellipsis, pathOptions);

while ( !line.canFit(tooBig)) {

if (tooBig.value.length > 1) {
tooBig = new Word(tooBig.value.slice(0,-2)+ellipsis, pathOptions);

// Try last word that fit in box?
} else if (!usingPreviousWord) {
tooBig = new Word(line.words.pop().value.slice(0,-2) + ellipsis, pathOptions);
usingPreviousWord = true;

} else {
break; // give up, only get 2 shots at this.
}
}

line.addWord(tooBig);
}
}

function getToWriteTextObjects(textObject = {}, pathOptions, textBox = {}) {
const toWriteTextObjects = [];
let text = ((textObject.prependValue) ? textObject.prependValue : '') +
Expand Down Expand Up @@ -529,9 +571,8 @@ <h1 class="page-title">text.js</h1>
// now deal with text line wrap (what happens to text that doesn't fit in line)
if (textBox.wrap !== 'auto') {
flushLine = true;
if (textBox.wrap === 'clip') {
newLine.addWord(word);
}
elideNonFittingText(textBox, newLine, word, pathOptions);

} else {
// this is the auto wrap section
newLine = new Line(lineMaxWidth, textBox.lineHeight, size, pathOptions);
Expand All @@ -548,13 +589,13 @@ <h1 class="page-title">text.js</h1>

if (flushLine) {
while (bk) {
bk = breaker.nextBreak();
if (bk &amp;&amp; bk.required) {
if (bk.required) {
flushLine = false;
newLine = new Line(lineMaxWidth, textBox.lineHeight, size, pathOptions);
word = null;
break;
}
bk = breaker.nextBreak();
}
} else {
/**
Expand Down Expand Up @@ -629,7 +670,7 @@ <h1 class="page-title">text.js</h1>
<br class="clear">

<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri Nov 01 2019 20:41:12 GMT-0400 (Eastern Daylight Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Nov 05 2019 10:28:09 GMT-0500 (Eastern Standard Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>

<script>prettyPrint();</script>
Expand Down
15 changes: 12 additions & 3 deletions lib/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ const xObjectForm = require('./xObjectForm');
* @param {number} [options.textBox.minHeight=0] - Text Box minimum height
* @param {number|number[]} [options.textBox.padding=0] - Text Box padding, [top, right, bottom, left]
* @param {number} [options.textBox.lineHeight=0] - Text Box line height
* @param {string} [options.textBox.wrap='auto'] - Text wrapping mechanism, 'auto', 'clip', 'trim', 'ellipsis'.
* @param {string|Boolean} [options.textBox.wrap='auto'] - Text wrapping mechanism, may be true, false,
* 'auto', 'clip', 'trim', 'ellipsis'. All the option values that are not equivalent to 'auto' dictate
* how the text which does not fit on a line is to be truncated. True is equivalent to 'auto'. False is equivalent to 'ellipsis'.
* @param {string} [options.textBox.textAlign='left top'] - Alignment inside text box, specified as 'horizontal vertical',
* where horizontal is one of: 'left', 'center', 'right', 'justify' and veritical is one of: 'top', 'center', 'bottom'.
* @param {Object} [options.textBox.style] - Text Box styles
Expand Down Expand Up @@ -101,6 +103,13 @@ exports.text = function text(text = '', x, y, options = {}) {
wrap: (options.textBox.wrap !== undefined) ? options.textBox.wrap : 'auto'
};

// allow user to treat wrap as boolean
if (textBox.wrap === true) {
textBox.wrap = 'auto';
} else if (textBox.wrap === false) {
textBox.wrap = 'ellipsis'
}

// Allows user to enter a single number which will be used for all text box sides,
// or an array of values [top, right, bottom, left] with any combination of missing sides.
// Default value for a missing side is the value of the text box's opposite side (see below).
Expand Down Expand Up @@ -449,7 +458,7 @@ function elideNonFittingText(textBox, line, word, pathOptions) {
// It makes an initial attempt to take the word that was
// too big and make it shrink in size until it and the
// ellipsis character fit. If that doesn't work, one more
// stab is taken by trying to shrink the previous word
// attempt is taken by trying to shrink the previous word
// that fit on the line.
const ellipsis = '…';
let usingPreviousWord = false;
Expand All @@ -462,7 +471,7 @@ function elideNonFittingText(textBox, line, word, pathOptions) {

// Try last word that fit in box?
} else if (!usingPreviousWord) {
tooBig = new Word(line.words.pop().value.slice(0,-2) + ellipsis, pathOptions);
tooBig = new Word(line.words.pop().value.slice(0,-1) + ellipsis, pathOptions);
usingPreviousWord = true;

} else {
Expand Down

0 comments on commit f0449db

Please sign in to comment.