From c465c7c611566e16539c1ffc14fb17036106b585 Mon Sep 17 00:00:00 2001 From: headlessNode Date: Thu, 24 Sep 2026 13:39:59 +0500 Subject: [PATCH 01/10] feat: add _tools/repl-txt/rules/no-premature-wrap --- .../@stdlib/_tools/repl-txt/wrap-text/bin/cli | 86 +++++++++ .../_tools/repl-txt/wrap-text/docs/usage.txt | 10 ++ .../repl-txt/wrap-text/etc/cli_opts.json | 28 +++ .../repl-txt/wrap-text/examples/index.js | 37 ++++ .../repl-txt/wrap-text/lib/break_classes.json | 15 ++ .../_tools/repl-txt/wrap-text/lib/index.js | 40 +++++ .../_tools/repl-txt/wrap-text/lib/main.js | 168 ++++++++++++++++++ .../_tools/repl-txt/wrap-text/package.json | 59 ++++++ .../_tools/repl-txt/wrap-text/test/test.js | 168 ++++++++++++++++++ 9 files changed, 611 insertions(+) create mode 100755 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/docs/usage.txt create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/break_classes.json create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/index.js create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/package.json create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli new file mode 100755 index 000000000000..b07ee941ab42 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli @@ -0,0 +1,86 @@ +#!/usr/bin/env node + +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var readFileSync = require( '@stdlib/fs/read-file' ).sync; +var stdin = require( '@stdlib/process/read-stdin' ); +var stdinStream = require( '@stdlib/streams/node/stdin' ); +var CLI = require( '@stdlib/cli/ctor' ); +var wrap = require( './../lib' ); + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +* @returns {void} +*/ +function main() { + var flags; + var args; + var cli; + + // Create a command-line interface: + cli = new CLI({ + 'pkg': require( './../package.json' ), + 'options': require( './../etc/cli_opts.json' ), + 'help': readFileSync( resolve( __dirname, '..', 'docs', 'usage.txt' ), { + 'encoding': 'utf8' + }) + }); + + // Get any provided command-line options: + flags = cli.flags(); + if ( flags.help || flags.version ) { + return; + } + + // Get any provided command-line arguments: + args = cli.args(); + + // Check if we are receiving data from `stdin`... + if ( !stdinStream.isTTY ) { + return stdin( onRead ); + } + console.log( wrap( args[ 0 ], flags.indent, flags[ 'max-width' ] ) ); // eslint-disable-line no-console + + /** + * Callback invoked upon reading from `stdin`. + * + * @private + * @param {(Error|null)} error - error object + * @param {Buffer} data - data + * @returns {void} + */ + function onRead( error, data ) { + if ( error ) { + return cli.error( error ); + } + console.log( wrap( data.toString(), flags.indent, flags[ 'max-width' ] ) ); // eslint-disable-line no-console + } +} + +main(); diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/docs/usage.txt b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/docs/usage.txt new file mode 100644 index 000000000000..84d29511dc3a --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/docs/usage.txt @@ -0,0 +1,10 @@ + +Usage: wrap-text [options] [str] + +Options: + + -h, --help Print this message. + -V, --version Print the package version. + -i, --indent indent Number of leading spaces per line. Default: 4. + -w, --max-width width Total line width limit. Default: 80. + diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json new file mode 100644 index 000000000000..5edb5a7ca682 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json @@ -0,0 +1,28 @@ +{ + "boolean": [ + "help", + "version" + ], + "integer": [ + "indent", + "max-width" + ], + "alias": { + "help": [ + "h" + ], + "version": [ + "V" + ], + "indent": [ + "i" + ], + "max-width": [ + "w" + ] + }, + "default": { + "indent": 4, + "max-width": 80 + } +} diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js new file mode 100644 index 000000000000..60462729f676 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js @@ -0,0 +1,37 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var wrap = require( './../lib' ); + +var txt = 'Beep boop foo bar.'; +var out = wrap( txt, 4 ); +console.log( out+'\n' ); + +txt = 'Rounds each element in a single-precision floating-point strided array `x` toward zero and assigns the results to elements in a single-precision floating-point strided array `y`.'; +out = wrap( txt, 4 ); +console.log( out+'\n' ); + +txt = 'Rounds each element in a single-precision floating-point strided array `x` toward positive infinity and assigns the results to elements in a single-precision floating-point strided array `y`.'; +out = wrap( txt, 4 ); +console.log( out+'\n' ); + +txt = 'Evaluates the ramp function for each element in a double-precision floating-point strided array `x` and assigns the results to elements in a double-precision floating-point strided array `y`.'; +out = wrap( txt, 4 ); +console.log( out+'\n' ); diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/break_classes.json b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/break_classes.json new file mode 100644 index 000000000000..2a17f9f03550 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/break_classes.json @@ -0,0 +1,15 @@ +{ + " ": "SP", + "-": "HY", + "(": "OP", + "[": "OP", + "{": "OP", + ")": "CL", + "]": "CL", + "}": "CL", + "`": "QU", + ".": "IS", + ",": "IS", + ":": "IS", + ";": "IS" +} diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/index.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/index.js new file mode 100644 index 000000000000..3b365fc67882 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Wrap text using a forward greedy algorithm with UAX #14-inspired break classes. +* +* @module @stdlib/_tools/repl-txt/wrap-text +* +* @example +* var wrap = require( '@stdlib/_tools/repl-txt/wrap-text' ); +* +* var out = wrap( 'This is a short line.', 4 ); +* // returns ' This is a short line.' +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js new file mode 100644 index 000000000000..8efe8aaae93d --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js @@ -0,0 +1,168 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var rtrim = require( '@stdlib/string/right-trim' ); +var repeat = require( '@stdlib/string/repeat' ); +var BREAK_CLASSES = require( './break_classes.json' ); + + +// VARIABLES // + +var MAX_WIDTH = 80; + + +// FUNCTIONS // + +/** +* Determines whether a break opportunity exists between two adjacent characters. +* +* @private +* @param {string} prev - break class of preceding character +* @param {string} next - break class of following character +* @returns {boolean} whether a break is allowed +*/ +function canBreak( prev, next ) { + if ( next === 'SP' ) { + return false; + } + if ( prev === 'SP' ) { + return true; + } + if ( next === 'CL' ) { + return false; + } + if ( next === 'IS' ) { + return false; + } + if ( prev === 'OP' ) { + return false; + } + if ( next === 'QU' ) { + return false; + } + if ( prev === 'QU' ) { + return false; + } + if ( prev === 'HY' ) { + return true; + } + return false; +} + +/** +* Finds break opportunities in a string and returns an array of break unit segments. +* +* @private +* @param {string} text - input string +* @returns {StringArray} array of break unit segments +*/ +function findBreakUnits( text ) { + var segments; + var start; + var prev; + var curr; + var len; + var i; + + len = text.length; + if ( len === 0 ) { + return [ '' ]; + } + segments = []; + start = 0; + prev = BREAK_CLASSES[ text.charAt( 0 ) ] || 'AL'; + + for ( i = 1; i < len; i++ ) { + curr = BREAK_CLASSES[ text.charAt( i ) ] || 'AL'; + if ( canBreak( prev, curr ) ) { + segments.push( text.substring( start, i ) ); + start = i; + } + prev = curr; + } + segments.push( text.substring( start ) ); + return segments; +} + + +// MAIN // + +/** +* Wraps repl text. +* +* @param {string} text - unwrapped single-paragraph text +* @param {NonNegativeInteger} indent - number of leading spaces per output line +* @param {PositiveInteger} [maxWidth=80] - total line width limit +* @returns {string} wrapped text with indent applied to each line +* +* @example +* var out = wrap( 'This is a short line.', 4 ); +* // returns ' This is a short line.' +*/ +function wrap( text, indent, maxWidth ) { + var contentWidth; + var segments; + var prefix; + var lines; + var line; + var seg; + var i; + + if ( arguments.length < 3 ) { + maxWidth = MAX_WIDTH; + } + prefix = repeat( ' ', indent ); + contentWidth = maxWidth - indent; + if ( contentWidth <= 0 || text.length === 0 ) { + return prefix + text; + } + segments = findBreakUnits( text ); + lines = []; + line = ''; + + for ( i = 0; i < segments.length; i++ ) { + seg = segments[ i ]; + if ( seg.length === 0 ) { + continue; + } + if ( line.length === 0 ) { + line = seg; + } else if ( rtrim( line + seg ).length <= contentWidth ) { + line += seg; + } else { + lines.push( prefix + rtrim( line ) ); + if ( seg.charAt( 0 ) === ' ' ) { + seg = seg.substring( 1 ); + } + line = seg; + } + } + if ( line.length > 0 ) { + lines.push( prefix + rtrim( line ) ); + } + return lines.join( '\n' ); +} + + +// EXPORTS // + +module.exports = wrap; diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/package.json b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/package.json new file mode 100644 index 000000000000..94234dd4f7b1 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/package.json @@ -0,0 +1,59 @@ +{ + "name": "@stdlib/_tools/repl-txt/wrap-text", + "version": "0.0.0", + "description": "Wrap text using a forward greedy algorithm with UAX #14-inspired break classes.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "bin": { + "wrap-text": "./bin/cli" + }, + "main": "./lib", + "directories": { + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "keywords": [ + "stdlib", + "tools", + "tool", + "repl", + "txt", + "repl.txt", + "docs", + "doc", + "text", + "wrap", + "format", + "fmt", + "greedy", + "uax14", + "line", + "break" + ] +} diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js new file mode 100644 index 000000000000..67b6aae32952 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js @@ -0,0 +1,168 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var wrap = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof wrap, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function wraps a provided text string', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'Computes the squared absolute value for each element in a strided array `x` and assigns the results to elements in a strided array `y`.'; + + expected = ' Computes the squared absolute value for each element in a strided array `x`\n and assigns the results to elements in a strided array `y`.'; + + actual = wrap( txt, 4 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function wraps a provided text string', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'Computes the absolute value of each element retrieved from a strided input array `x` via a callback function and assigns each result to an element in a strided output array `y`.'; + + expected = ' Computes the absolute value of each element retrieved from a strided input\n array `x` via a callback function and assigns each result to an element in a\n strided output array `y`.'; + + actual = wrap( txt, 4 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function wraps a provided text string', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'Computes the squared absolute value for each element in a strided array `x` and assigns the results to elements in a strided array `y` using alternative indexing semantics.'; + + expected = ' Computes the squared absolute value for each element in a strided array `x`\n and assigns the results to elements in a strided array `y` using alternative\n indexing semantics.'; + + actual = wrap( txt, 4 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function wraps a provided text string', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'Returns a function which dispatches to specified functions based on input argument types.'; + + expected = ' Returns a function which dispatches to specified functions based on input\n argument types.'; + + actual = wrap( txt, 4 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function does not break before close punctuation', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'Computes the absolute value of a double-precision floating-point number `x`.'; + + expected = ' Computes the absolute value of a double-precision floating-point number `x`.'; + + actual = wrap( txt, 4 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function breaks at hyphens', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'however, that values between `start` and `stop` are subject to floating-point rounding errors.'; + + expected = ' however, that values between `start` and `stop` are subject to floating-\n point rounding errors.'; + + actual = wrap( txt, 4 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function supports custom indent levels', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'Number of indexed elements.'; + + expected = ' Number of indexed elements.'; + + actual = wrap( txt, 8 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function supports a custom max width', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'This is a floating-point double-precision value.'; + + expected = ' This is a floating-point\n double-precision value.'; + + actual = wrap( txt, 4, 32 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns text unchanged if it fits on one line', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'Short text.'; + + expected = ' Short text.'; + + actual = wrap( txt, 4 ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); From c4d8065564d0e6389956f9745c03f36b95d75ce8 Mon Sep 17 00:00:00 2001 From: headlessNode Date: Fri, 25 Sep 2026 18:47:21 +0500 Subject: [PATCH 02/10] fix: apply suggestions from code review --- .../@stdlib/_tools/repl-txt/wrap-text/bin/cli | 14 +++++- .../repl-txt/wrap-text/etc/cli_opts.json | 4 -- .../repl-txt/wrap-text/examples/index.js | 8 ++-- .../_tools/repl-txt/wrap-text/lib/index.js | 2 +- .../_tools/repl-txt/wrap-text/lib/main.js | 36 +++++++++----- .../_tools/repl-txt/wrap-text/test/test.js | 48 +++++++++++++++---- 6 files changed, 80 insertions(+), 32 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli index b07ee941ab42..e746011bc2a3 100755 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli @@ -41,6 +41,7 @@ var wrap = require( './../lib' ); function main() { var flags; var args; + var opts; var cli; // Create a command-line interface: @@ -61,11 +62,20 @@ function main() { // Get any provided command-line arguments: args = cli.args(); + // Build options... + opts = {}; + if ( flags.indent !== void 0 ) { + opts.indent = flags.indent; + } + if ( flags[ 'max-width' ] !== void 0 ) { + opts.maxWidth = flags[ 'max-width' ]; + } + // Check if we are receiving data from `stdin`... if ( !stdinStream.isTTY ) { return stdin( onRead ); } - console.log( wrap( args[ 0 ], flags.indent, flags[ 'max-width' ] ) ); // eslint-disable-line no-console + console.log( wrap( args[ 0 ], opts ) ); // eslint-disable-line no-console /** * Callback invoked upon reading from `stdin`. @@ -79,7 +89,7 @@ function main() { if ( error ) { return cli.error( error ); } - console.log( wrap( data.toString(), flags.indent, flags[ 'max-width' ] ) ); // eslint-disable-line no-console + console.log( wrap( data.toString(), opts ) ); // eslint-disable-line no-console } } diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json index 5edb5a7ca682..217f89201179 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json @@ -20,9 +20,5 @@ "max-width": [ "w" ] - }, - "default": { - "indent": 4, - "max-width": 80 } } diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js index 60462729f676..b43dc80d3dc2 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js @@ -21,17 +21,17 @@ var wrap = require( './../lib' ); var txt = 'Beep boop foo bar.'; -var out = wrap( txt, 4 ); +var out = wrap( txt ); console.log( out+'\n' ); txt = 'Rounds each element in a single-precision floating-point strided array `x` toward zero and assigns the results to elements in a single-precision floating-point strided array `y`.'; -out = wrap( txt, 4 ); +out = wrap( txt ); console.log( out+'\n' ); txt = 'Rounds each element in a single-precision floating-point strided array `x` toward positive infinity and assigns the results to elements in a single-precision floating-point strided array `y`.'; -out = wrap( txt, 4 ); +out = wrap( txt ); console.log( out+'\n' ); txt = 'Evaluates the ramp function for each element in a double-precision floating-point strided array `x` and assigns the results to elements in a double-precision floating-point strided array `y`.'; -out = wrap( txt, 4 ); +out = wrap( txt ); console.log( out+'\n' ); diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/index.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/index.js index 3b365fc67882..604bb9cee830 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/index.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/index.js @@ -26,7 +26,7 @@ * @example * var wrap = require( '@stdlib/_tools/repl-txt/wrap-text' ); * -* var out = wrap( 'This is a short line.', 4 ); +* var out = wrap( 'This is a short line.' ); * // returns ' This is a short line.' */ diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js index 8efe8aaae93d..da0f791936b0 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js @@ -20,6 +20,7 @@ // MODULES // +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); var rtrim = require( '@stdlib/string/right-trim' ); var repeat = require( '@stdlib/string/repeat' ); var BREAK_CLASSES = require( './break_classes.json' ); @@ -84,9 +85,6 @@ function findBreakUnits( text ) { var i; len = text.length; - if ( len === 0 ) { - return [ '' ]; - } segments = []; start = 0; prev = BREAK_CLASSES[ text.charAt( 0 ) ] || 'AL'; @@ -110,31 +108,45 @@ function findBreakUnits( text ) { * Wraps repl text. * * @param {string} text - unwrapped single-paragraph text -* @param {NonNegativeInteger} indent - number of leading spaces per output line -* @param {PositiveInteger} [maxWidth=80] - total line width limit +* @param {Object} [options] - options +* @param {NonNegativeInteger} [options.indent=4] - number of leading spaces per output line +* @param {PositiveInteger} [options.maxWidth=80] - total line width limit * @returns {string} wrapped text with indent applied to each line * * @example -* var out = wrap( 'This is a short line.', 4 ); +* var out = wrap( 'This is a short line.' ); * // returns ' This is a short line.' */ -function wrap( text, indent, maxWidth ) { +function wrap( text, options ) { var contentWidth; var segments; + var maxWidth; var prefix; + var indent; var lines; var line; var seg; var i; - if ( arguments.length < 3 ) { - maxWidth = MAX_WIDTH; + indent = 4; + maxWidth = MAX_WIDTH; + if ( arguments.length > 1 ) { + if ( hasOwnProp( options, 'indent' ) ) { + indent = options.indent; + } + if ( hasOwnProp( options, 'maxWidth' ) ) { + maxWidth = options.maxWidth; + } } - prefix = repeat( ' ', indent ); contentWidth = maxWidth - indent; - if ( contentWidth <= 0 || text.length === 0 ) { - return prefix + text; + if ( contentWidth <= 0 ) { + indent = 0; + contentWidth = maxWidth; + } + if ( text.length === 0 ) { + return ''; } + prefix = repeat( ' ', indent ); segments = findBreakUnits( text ); lines = []; line = ''; diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js index 67b6aae32952..846985ce3d9e 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js @@ -41,7 +41,7 @@ tape( 'the function wraps a provided text string', function test( t ) { expected = ' Computes the squared absolute value for each element in a strided array `x`\n and assigns the results to elements in a strided array `y`.'; - actual = wrap( txt, 4 ); + actual = wrap( txt ); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); @@ -56,7 +56,7 @@ tape( 'the function wraps a provided text string', function test( t ) { expected = ' Computes the absolute value of each element retrieved from a strided input\n array `x` via a callback function and assigns each result to an element in a\n strided output array `y`.'; - actual = wrap( txt, 4 ); + actual = wrap( txt ); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); @@ -71,7 +71,7 @@ tape( 'the function wraps a provided text string', function test( t ) { expected = ' Computes the squared absolute value for each element in a strided array `x`\n and assigns the results to elements in a strided array `y` using alternative\n indexing semantics.'; - actual = wrap( txt, 4 ); + actual = wrap( txt ); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); @@ -86,7 +86,7 @@ tape( 'the function wraps a provided text string', function test( t ) { expected = ' Returns a function which dispatches to specified functions based on input\n argument types.'; - actual = wrap( txt, 4 ); + actual = wrap( txt ); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); @@ -101,7 +101,7 @@ tape( 'the function does not break before close punctuation', function test( t ) expected = ' Computes the absolute value of a double-precision floating-point number `x`.'; - actual = wrap( txt, 4 ); + actual = wrap( txt ); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); @@ -116,7 +116,7 @@ tape( 'the function breaks at hyphens', function test( t ) { expected = ' however, that values between `start` and `stop` are subject to floating-\n point rounding errors.'; - actual = wrap( txt, 4 ); + actual = wrap( txt ); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); @@ -131,7 +131,9 @@ tape( 'the function supports custom indent levels', function test( t ) { expected = ' Number of indexed elements.'; - actual = wrap( txt, 8 ); + actual = wrap( txt, { + 'indent': 8 + }); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); @@ -146,7 +148,10 @@ tape( 'the function supports a custom max width', function test( t ) { expected = ' This is a floating-point\n double-precision value.'; - actual = wrap( txt, 4, 32 ); + actual = wrap( txt, { + 'indent': 4, + 'maxWidth': 32 + }); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); @@ -161,8 +166,33 @@ tape( 'the function returns text unchanged if it fits on one line', function tes expected = ' Short text.'; - actual = wrap( txt, 4 ); + actual = wrap( txt ); t.strictEqual( actual, expected, 'returns expected value' ); t.end(); }); + +tape( 'the function drops indent when indent is greater than or equal to max width', function test( t ) { + var expected; + var actual; + var txt; + + txt = 'hello world foo bar'; + + expected = 'hello\nworld\nfoo\nbar'; + + actual = wrap( txt, { + 'indent': 4, + 'maxWidth': 4 + }); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns an empty string for empty text', function test( t ) { + var actual = wrap( '' ); + + t.strictEqual( actual, '', 'returns expected value' ); + t.end(); +}); From 4aa73d739975f1420a77722321a09827eaed742f Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 25 Sep 2026 20:44:43 -0700 Subject: [PATCH 03/10] fix: remove aliases Signed-off-by: Athan --- .../@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json index 217f89201179..e6e97eff8f1e 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json @@ -13,12 +13,6 @@ ], "version": [ "V" - ], - "indent": [ - "i" - ], - "max-width": [ - "w" ] } } From 6927aa38f7a1c998d03235713e018e50ea50a014 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 25 Sep 2026 20:46:28 -0700 Subject: [PATCH 04/10] docs: update type Signed-off-by: Athan --- lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js index da0f791936b0..a9e7f9430043 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js @@ -74,7 +74,7 @@ function canBreak( prev, next ) { * * @private * @param {string} text - input string -* @returns {StringArray} array of break unit segments +* @returns {Array} array of break unit segments */ function findBreakUnits( text ) { var segments; From e40c866ba4906fa0718729bc484f75cf756a23c4 Mon Sep 17 00:00:00 2001 From: headlessNode Date: Sat, 26 Sep 2026 11:07:56 +0500 Subject: [PATCH 05/10] refactor: apply suggestions from code review --- .../_tools/repl-txt/wrap-text/lib/main.js | 36 ++--- .../_tools/repl-txt/wrap-text/lib/validate.js | 76 +++++++++ .../_tools/repl-txt/wrap-text/test/test.js | 140 +++++++++++++--- .../repl-txt/wrap-text/test/test.validate.js | 152 ++++++++++++++++++ 4 files changed, 360 insertions(+), 44 deletions(-) create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/validate.js create mode 100644 lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js index a9e7f9430043..079a7b67af94 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js @@ -20,17 +20,13 @@ // MODULES // -var hasOwnProp = require( '@stdlib/assert/has-own-property' ); var rtrim = require( '@stdlib/string/right-trim' ); var repeat = require( '@stdlib/string/repeat' ); +var format = require( '@stdlib/string/format' ); +var validate = require( './validate.js' ); var BREAK_CLASSES = require( './break_classes.json' ); -// VARIABLES // - -var MAX_WIDTH = 80; - - // FUNCTIONS // /** @@ -111,6 +107,9 @@ function findBreakUnits( text ) { * @param {Object} [options] - options * @param {NonNegativeInteger} [options.indent=4] - number of leading spaces per output line * @param {PositiveInteger} [options.maxWidth=80] - total line width limit +* @throws {TypeError} options argument must be an object +* @throws {TypeError} must provide valid options +* @throws {RangeError} `options.maxWidth` must be greater than `options.indent` * @returns {string} wrapped text with indent applied to each line * * @example @@ -120,33 +119,32 @@ function findBreakUnits( text ) { function wrap( text, options ) { var contentWidth; var segments; - var maxWidth; var prefix; - var indent; var lines; + var opts; var line; + var err; var seg; var i; - indent = 4; - maxWidth = MAX_WIDTH; + opts = { + 'indent': 4, + 'maxWidth': 80 + }; if ( arguments.length > 1 ) { - if ( hasOwnProp( options, 'indent' ) ) { - indent = options.indent; - } - if ( hasOwnProp( options, 'maxWidth' ) ) { - maxWidth = options.maxWidth; + err = validate( opts, options ); + if ( err ) { + throw err; } } - contentWidth = maxWidth - indent; + contentWidth = opts.maxWidth - opts.indent; if ( contentWidth <= 0 ) { - indent = 0; - contentWidth = maxWidth; + throw new RangeError( format( 'invalid option. `%s` option must be greater than `%s` option. Options: `%u`, `%u`.', 'maxWidth', 'indent', opts.maxWidth, opts.indent ) ); } if ( text.length === 0 ) { return ''; } - prefix = repeat( ' ', indent ); + prefix = repeat( ' ', opts.indent ); segments = findBreakUnits( text ); lines = []; line = ''; diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/validate.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/validate.js new file mode 100644 index 000000000000..da8584391045 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/validate.js @@ -0,0 +1,76 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var isObject = require( '@stdlib/assert/is-plain-object' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; +var isPositiveInteger = require( '@stdlib/assert/is-positive-integer' ).isPrimitive; +var format = require( '@stdlib/string/format' ); + + +// MAIN // + +/** +* Validates function options. +* +* @private +* @param {Object} opts - destination object +* @param {Options} options - function options +* @param {NonNegativeInteger} [options.indent] - number of leading spaces per output line +* @param {PositiveInteger} [options.maxWidth] - total line width limit +* @returns {(Error|null)} error object or null +* +* @example +* var opts = {}; +* var options = { +* 'indent': 4, +* 'maxWidth': 80 +* }; +* +* var err = validate( opts, options ); +* if ( err ) { +* throw err; +* } +*/ +function validate( opts, options ) { + if ( !isObject( options ) ) { + return new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) ); + } + if ( hasOwnProp( options, 'indent' ) ) { + opts.indent = options.indent; + if ( !isNonNegativeInteger( opts.indent ) ) { + return new TypeError( format( 'invalid option. `%s` option must be a nonnegative integer. Option: `%s`.', 'indent', opts.indent ) ); + } + } + if ( hasOwnProp( options, 'maxWidth' ) ) { + opts.maxWidth = options.maxWidth; + if ( !isPositiveInteger( opts.maxWidth ) ) { + return new TypeError( format( 'invalid option. `%s` option must be a positive integer. Option: `%s`.', 'maxWidth', opts.maxWidth ) ); + } + } + return null; +} + + +// EXPORTS // + +module.exports = validate; diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js index 846985ce3d9e..108a510ab978 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js @@ -32,6 +32,121 @@ tape( 'main export is a function', function test( t ) { t.end(); }); +tape( 'the function throws an error if provided an `options` argument which is not an object', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + true, + null, + void 0, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws a type error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function throws() { + wrap( 'hello world', value ); + }; + } +}); + +tape( 'the function throws an error if provided an `options.indent` which is not a nonnegative integer', function test( t ) { + var values; + var i; + + values = [ + -1, + 3.14, + NaN, + '5', + true, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws a type error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function throws() { + var opts = { + 'indent': value + }; + wrap( 'hello world', opts ); + }; + } +}); + +tape( 'the function throws an error if provided an `options.maxWidth` which is not a positive integer', function test( t ) { + var values; + var i; + + values = [ + 0, + -1, + 3.14, + NaN, + '5', + true, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws a type error when provided ' + values[ i ] ); + } + t.end(); + + function badValue( value ) { + return function throws() { + var opts = { + 'maxWidth': value + }; + wrap( 'hello world', opts ); + }; + } +}); + +tape( 'the function throws an error if `options.maxWidth` is less than or equal to `options.indent`', function test( t ) { + t.throws( badValue( 4 ), RangeError, 'throws a range error' ); + t.throws( badValue( 3 ), RangeError, 'throws a range error' ); + t.end(); + + function badValue( maxWidth ) { + return function throws() { + var opts = { + 'indent': 4, + 'maxWidth': maxWidth + }; + wrap( 'hello world', opts ); + }; + } +}); + +tape( 'the function returns an empty string for empty text', function test( t ) { + var actual = wrap( '' ); + + t.strictEqual( actual, '', 'returns expected value' ); + t.end(); +}); + tape( 'the function wraps a provided text string', function test( t ) { var expected; var actual; @@ -171,28 +286,3 @@ tape( 'the function returns text unchanged if it fits on one line', function tes t.strictEqual( actual, expected, 'returns expected value' ); t.end(); }); - -tape( 'the function drops indent when indent is greater than or equal to max width', function test( t ) { - var expected; - var actual; - var txt; - - txt = 'hello world foo bar'; - - expected = 'hello\nworld\nfoo\nbar'; - - actual = wrap( txt, { - 'indent': 4, - 'maxWidth': 4 - }); - - t.strictEqual( actual, expected, 'returns expected value' ); - t.end(); -}); - -tape( 'the function returns an empty string for empty text', function test( t ) { - var actual = wrap( '' ); - - t.strictEqual( actual, '', 'returns expected value' ); - t.end(); -}); diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js new file mode 100644 index 000000000000..fede8d2efec2 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js @@ -0,0 +1,152 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var validate = require( './../lib/validate.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof validate, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an error if provided an `options` argument which is not an object', function test( t ) { + var values; + var err; + var i; + + values = [ + '5', + 5, + NaN, + true, + null, + void 0, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + err = validate( {}, values[ i ] ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided ' + values[ i ] ); + } + t.end(); +}); + +tape( 'the function returns an error if provided an `options.indent` which is not a nonnegative integer', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + -1, + 3.14, + NaN, + '5', + true, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'indent': values[ i ] + }; + err = validate( {}, opts ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided ' + values[ i ] ); + } + t.end(); +}); + +tape( 'the function returns an error if provided an `options.maxWidth` which is not a positive integer', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + 0, + -1, + 3.14, + NaN, + '5', + true, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'maxWidth': values[ i ] + }; + err = validate( {}, opts ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error when provided ' + values[ i ] ); + } + t.end(); +}); + +tape( 'the function does not return an error if provided valid options', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'indent': 8, + 'maxWidth': 80 + }; + err = validate( opts, options ); + + t.strictEqual( err, null, 'returns expected value' ); + t.strictEqual( opts.indent, 8, 'sets indent option' ); + t.strictEqual( opts.maxWidth, 80, 'sets maxWidth option' ); + + t.end(); +}); + +tape( 'the function ignores unsupported/unrecognized options', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'beep': 'boop', + 'a': 'b' + }; + err = validate( opts, options ); + + t.strictEqual( err, null, 'returns expected value' ); + t.deepEqual( opts, {}, 'does not set any options' ); + + t.end(); +}); From 72fa876b3512e0ab7ec0dcfd8586023727d03950 Mon Sep 17 00:00:00 2001 From: Athan Date: Sat, 26 Sep 2026 00:05:03 -0700 Subject: [PATCH 06/10] Apply batched suggestions from code review Co-authored-by: Athan Signed-off-by: Athan --- .../@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js index fede8d2efec2..1c68dedb7a3b 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js @@ -55,7 +55,7 @@ tape( 'the function returns an error if provided an `options` argument which is t.end(); }); -tape( 'the function returns an error if provided an `options.indent` which is not a nonnegative integer', function test( t ) { +tape( 'the function returns an error if provided an `indent` option which is not a nonnegative integer', function test( t ) { var values; var opts; var err; @@ -84,7 +84,7 @@ tape( 'the function returns an error if provided an `options.indent` which is no t.end(); }); -tape( 'the function returns an error if provided an `options.maxWidth` which is not a positive integer', function test( t ) { +tape( 'the function returns an error if provided a `maxWidth` option which is not a positive integer', function test( t ) { var values; var opts; var err; From 6be40f1281735650d400acf967a05706e42c0c56 Mon Sep 17 00:00:00 2001 From: Athan Date: Sat, 26 Sep 2026 00:05:59 -0700 Subject: [PATCH 07/10] Apply batched suggestions from code review Co-authored-by: Athan Signed-off-by: Athan --- .../@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js index 1c68dedb7a3b..7f94e2fe515f 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.validate.js @@ -127,8 +127,8 @@ tape( 'the function does not return an error if provided valid options', functio err = validate( opts, options ); t.strictEqual( err, null, 'returns expected value' ); - t.strictEqual( opts.indent, 8, 'sets indent option' ); - t.strictEqual( opts.maxWidth, 80, 'sets maxWidth option' ); + t.strictEqual( opts.indent, 8, 'returns expected value' ); + t.strictEqual( opts.maxWidth, 80, 'returns expected value' ); t.end(); }); @@ -146,7 +146,7 @@ tape( 'the function ignores unsupported/unrecognized options', function test( t err = validate( opts, options ); t.strictEqual( err, null, 'returns expected value' ); - t.deepEqual( opts, {}, 'does not set any options' ); + t.deepEqual( opts, {}, 'returns expected value' ); t.end(); }); From b586cae0e3de4c7c438cecee258b5354317a281f Mon Sep 17 00:00:00 2001 From: Athan Date: Sat, 26 Sep 2026 00:07:06 -0700 Subject: [PATCH 08/10] Apply batched suggestions from code review Co-authored-by: Athan Signed-off-by: Athan --- .../@stdlib/_tools/repl-txt/wrap-text/test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js index 108a510ab978..3cbaa3614a40 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js @@ -59,7 +59,7 @@ tape( 'the function throws an error if provided an `options` argument which is n } }); -tape( 'the function throws an error if provided an `options.indent` which is not a nonnegative integer', function test( t ) { +tape( 'the function throws an error if provided an `indent` option which is not a nonnegative integer', function test( t ) { var values; var i; @@ -91,7 +91,7 @@ tape( 'the function throws an error if provided an `options.indent` which is not } }); -tape( 'the function throws an error if provided an `options.maxWidth` which is not a positive integer', function test( t ) { +tape( 'the function throws an error if provided a `maxWidth` option which is not a positive integer', function test( t ) { var values; var i; From 7d6c15799c1ac5c6d1f8f7083f21d292579d8524 Mon Sep 17 00:00:00 2001 From: Athan Date: Sat, 26 Sep 2026 00:11:41 -0700 Subject: [PATCH 09/10] refactor: update error message Signed-off-by: Athan --- lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js index 079a7b67af94..cbbd7ffb7c7a 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js @@ -139,7 +139,7 @@ function wrap( text, options ) { } contentWidth = opts.maxWidth - opts.indent; if ( contentWidth <= 0 ) { - throw new RangeError( format( 'invalid option. `%s` option must be greater than `%s` option. Options: `%u`, `%u`.', 'maxWidth', 'indent', opts.maxWidth, opts.indent ) ); + throw new RangeError( format( 'invalid option. `%s` must be greater than `%s`. %s: `%u`. %s: `%u`.', 'maxWidth', 'indent', 'maxWidth', 'indent', opts.maxWidth, opts.indent ) ); } if ( text.length === 0 ) { return ''; From 2b250b86136a8723cd93b2fe9e364e4b9ea0295a Mon Sep 17 00:00:00 2001 From: headlessNode Date: Sat, 26 Sep 2026 14:44:31 +0500 Subject: [PATCH 10/10] refactor: apply suggestions from code review --- .../repl-txt/wrap-text/examples/index.js | 69 +++++ .../_tools/repl-txt/wrap-text/lib/main.js | 80 +++-- .../_tools/repl-txt/wrap-text/test/test.js | 277 ++++++++++++++++++ 3 files changed, 401 insertions(+), 25 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js index b43dc80d3dc2..5aadf18b046f 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js @@ -35,3 +35,72 @@ console.log( out+'\n' ); txt = 'Evaluates the ramp function for each element in a double-precision floating-point strided array `x` and assigns the results to elements in a double-precision floating-point strided array `y`.'; out = wrap( txt ); console.log( out+'\n' ); + +txt = [ + 'Generates a double-precision floating-point Vandermonde matrix.', + '', + 'When the mode is positive, the matrix is generated such that', + '', + ' [', + ' 1 x_0^1 x_0^2 ... x_0^(N-1)', + ' 1 x_1^1 x_1^2 ... x_1^(N-1)', + ' ...', + ' ]', + '', + 'with increasing powers along the rows.' +].join( '\n' ); +out = wrap( txt ); +console.log( out+'\n' ); + +txt = [ + 'Initializes a single-precision floating-point workspace array for performing a real-valued Fourier transform.', + '', + 'The workspace array is divided into three sections:', + '', + '1. scratch/workspace: the section ranges from indices 0 to N-1 and is used while performing transforms. This section is not updated during initialization.', + '', + '2. twiddle factors: the section ranges from indices N to 2N-1 and stores a table of reusable complex exponential constants as cosine/sine pairs.' +].join( '\n' ); +out = wrap( txt ); +console.log( out+'\n' ); + +txt = [ + 'Converts an array to an object supporting fancy indexing.', + '', + 'Fancy arrays support broadcasting in which assigned scalars and single-element arrays are repeated (without additional memory allocation) to match the length of a target array instance.' +].join( '\n' ); +out = wrap( txt ); +console.log( out+'\n' ); + +txt = [ + 'In octal representation, a mask is a four digit number, e.g., 0077, comprised as follows:', + '', + '- 0: special permissions (setuid, setgid, sticky bit)', + '- 0: (u)ser/owner permissions', + '- 7: (g)roup permissions', + '- 7: (o)thers/non-group permissions', + '', + 'Permissions can be represented using the following symbolic form:', + '', + ' u=rwx,g=rwx,o=rwx' +].join( '\n' ); +out = wrap( txt ); +console.log( out+'\n' ); + +txt = [ + 'Applies a real elementary reflector `H = I - tau * v * v^T` to a real M by N matrix `C`.', + '', + 'If `side = \'left\'`,', + '', + '- `work` should have `N` indexed elements.', + '- `V` should have `1 + (M-1) * abs(strideV)` indexed elements.', + '- `C` is overwritten by `H * C`.', + '', + 'If `side = \'right\'`,', + '', + '- `work` should have `M` indexed elements.', + '- `V` should have `1 + (N-1) * abs(strideV)` indexed elements.', + '- `C` is overwritten by `C * H`.' +].join( '\n' ); +out = wrap( txt ); +console.log( out+'\n' ); diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js index cbbd7ffb7c7a..1822b467715e 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js @@ -97,13 +97,56 @@ function findBreakUnits( text ) { return segments; } +/** +* Wraps a single line of text. +* +* @private +* @param {string} text - line text +* @param {PositiveInteger} contentWidth - available content width +* @param {string} prefix - indent prefix string +* @returns {string} wrapped line with indent applied +*/ +function wrapLine( text, contentWidth, prefix ) { + var segments; + var lines; + var line; + var seg; + var i; + + segments = findBreakUnits( text ); + lines = []; + line = ''; + + for ( i = 0; i < segments.length; i++ ) { + seg = segments[ i ]; + if ( seg.length === 0 ) { + continue; + } + if ( line.length === 0 ) { + line = seg; + } else if ( rtrim( line + seg ).length <= contentWidth ) { + line += seg; + } else { + lines.push( prefix + rtrim( line ) ); + if ( seg.charAt( 0 ) === ' ' ) { + seg = seg.substring( 1 ); + } + line = seg; + } + } + if ( line.length > 0 ) { + lines.push( prefix + rtrim( line ) ); + } + return lines.join( '\n' ); +} + // MAIN // /** * Wraps repl text. * -* @param {string} text - unwrapped single-paragraph text +* @param {string} text - input text * @param {Object} [options] - options * @param {NonNegativeInteger} [options.indent=4] - number of leading spaces per output line * @param {PositiveInteger} [options.maxWidth=80] - total line width limit @@ -118,13 +161,12 @@ function findBreakUnits( text ) { */ function wrap( text, options ) { var contentWidth; - var segments; + var output; var prefix; var lines; var opts; var line; var err; - var seg; var i; opts = { @@ -139,37 +181,25 @@ function wrap( text, options ) { } contentWidth = opts.maxWidth - opts.indent; if ( contentWidth <= 0 ) { - throw new RangeError( format( 'invalid option. `%s` must be greater than `%s`. %s: `%u`. %s: `%u`.', 'maxWidth', 'indent', 'maxWidth', 'indent', opts.maxWidth, opts.indent ) ); + throw new RangeError( format( 'invalid option. `%s` must be greater than `%s`. %s: `%u`. %s: `%u`.', 'maxWidth', 'indent', 'maxWidth', opts.maxWidth, 'indent', opts.indent ) ); } if ( text.length === 0 ) { return ''; } prefix = repeat( ' ', opts.indent ); - segments = findBreakUnits( text ); - lines = []; - line = ''; - - for ( i = 0; i < segments.length; i++ ) { - seg = segments[ i ]; - if ( seg.length === 0 ) { - continue; - } + lines = text.split( '\n' ); + output = []; + for ( i = 0; i < lines.length; i++ ) { + line = lines[ i ]; if ( line.length === 0 ) { - line = seg; - } else if ( rtrim( line + seg ).length <= contentWidth ) { - line += seg; + output.push( '' ); + } else if ( line.charAt( 0 ) === ' ' || line.charAt( 0 ) === '\t' ) { + output.push( prefix + line ); } else { - lines.push( prefix + rtrim( line ) ); - if ( seg.charAt( 0 ) === ' ' ) { - seg = seg.substring( 1 ); - } - line = seg; + output.push( wrapLine( line, contentWidth, prefix ) ); } } - if ( line.length > 0 ) { - lines.push( prefix + rtrim( line ) ); - } - return lines.join( '\n' ); + return output.join( '\n' ); } diff --git a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js index 3cbaa3614a40..0b3dc743527e 100644 --- a/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js @@ -286,3 +286,280 @@ tape( 'the function returns text unchanged if it fits on one line', function tes t.strictEqual( actual, expected, 'returns expected value' ); t.end(); }); + +tape( 'the function preserves multi-paragraph text with indented code blocks', function test( t ) { + var expected; + var actual; + var txt; + + txt = [ + 'Generates a double-precision floating-point Vandermonde matrix.', + '', + 'When the mode is positive, the matrix is generated such that', + '', + ' [', + ' 1 x_0^1 x_0^2 ... x_0^(N-1)', + ' 1 x_1^1 x_1^2 ... x_1^(N-1)', + ' ...', + ' ]', + '', + 'with increasing powers along the rows.', + '', + 'When the mode is negative, the matrix is generated such that', + '', + ' [', + ' x_0^(N-1) ... x_0^2 x_0^1 1', + ' x_1^(N-1) ... x_1^2 x_1^1 1', + ' ...', + ' ]', + '', + 'with decreasing powers along the rows.', + '', + 'If `M <= 0` or `N <= 0`, the function returns the output matrix unchanged.' + ].join( '\n' ); + + expected = [ + ' Generates a double-precision floating-point Vandermonde matrix.', + '', + ' When the mode is positive, the matrix is generated such that', + '', + ' [', + ' 1 x_0^1 x_0^2 ... x_0^(N-1)', + ' 1 x_1^1 x_1^2 ... x_1^(N-1)', + ' ...', + ' ]', + '', + ' with increasing powers along the rows.', + '', + ' When the mode is negative, the matrix is generated such that', + '', + ' [', + ' x_0^(N-1) ... x_0^2 x_0^1 1', + ' x_1^(N-1) ... x_1^2 x_1^1 1', + ' ...', + ' ]', + '', + ' with decreasing powers along the rows.', + '', + ' If `M <= 0` or `N <= 0`, the function returns the output matrix unchanged.' + ].join( '\n' ); + + actual = wrap( txt ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function wraps multi-paragraph text with numbered list items', function test( t ) { + var expected; + var actual; + var txt; + + txt = [ + 'Initializes a single-precision floating-point workspace array for performing a real-valued Fourier transform.', + '', + 'The workspace array is divided into three sections:', + '', + '1. scratch/workspace: the section ranges from indices 0 to N-1 and is used while performing transforms. This section is not updated during initialization.', + '', + '2. twiddle factors: the section ranges from indices N to 2N-1 and stores a table of reusable complex exponential constants as cosine/sine pairs.', + '', + '3. radix factor table: the section starts at index 2N and stores the sequence length N, the number of factors into which N was decomposed, and the individual integer radix factors.', + '', + 'Any remaining array space remains as unused storage.' + ].join( '\n' ); + + expected = [ + ' Initializes a single-precision floating-point workspace array for performing', + ' a real-valued Fourier transform.', + '', + ' The workspace array is divided into three sections:', + '', + ' 1. scratch/workspace: the section ranges from indices 0 to N-1 and is used', + ' while performing transforms. This section is not updated during', + ' initialization.', + '', + ' 2. twiddle factors: the section ranges from indices N to 2N-1 and stores a', + ' table of reusable complex exponential constants as cosine/sine pairs.', + '', + ' 3. radix factor table: the section starts at index 2N and stores the', + ' sequence length N, the number of factors into which N was decomposed, and', + ' the individual integer radix factors.', + '', + ' Any remaining array space remains as unused storage.' + ].join( '\n' ); + + actual = wrap( txt ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function wraps multi-paragraph text with hyphen breaks', function test( t ) { + var expected; + var actual; + var txt; + + txt = [ + 'Converts an array to an object supporting fancy indexing.', + '', + 'Fancy arrays support broadcasting in which assigned scalars and single-element arrays are repeated (without additional memory allocation) to match the length of a target array instance.', + '', + 'Consequently, when assigning arrays to slices, the array on the right-hand-side must be broadcast-compatible with number of elements in the slice.' + ].join( '\n' ); + + expected = [ + ' Converts an array to an object supporting fancy indexing.', + '', + ' Fancy arrays support broadcasting in which assigned scalars and single-', + ' element arrays are repeated (without additional memory allocation) to match', + ' the length of a target array instance.', + '', + ' Consequently, when assigning arrays to slices, the array on the right-hand-', + ' side must be broadcast-compatible with number of elements in the slice.' + ].join( '\n' ); + + actual = wrap( txt ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function wraps text with bullet lists and indented code blocks', function test( t ) { + var expected; + var actual; + var txt; + + txt = [ + 'In octal representation, a mask is a four digit number, e.g., 0077, comprised as follows:', + '', + '- 0: special permissions (setuid, setgid, sticky bit)', + '- 0: (u)ser/owner permissions', + '- 7: (g)roup permissions', + '- 7: (o)thers/non-group permissions', + '', + 'Permissions can be represented using the following symbolic form:', + '', + ' u=rwx,g=rwx,o=rwx', + '', + 'where', + '', + '- u: user permissions', + '- g: group permissions', + '- o: other/non-group permissions', + '- r: read', + '- w: write', + '- x: execute' + ].join( '\n' ); + + expected = [ + ' In octal representation, a mask is a four digit number, e.g., 0077,', + ' comprised as follows:', + '', + ' - 0: special permissions (setuid, setgid, sticky bit)', + ' - 0: (u)ser/owner permissions', + ' - 7: (g)roup permissions', + ' - 7: (o)thers/non-group permissions', + '', + ' Permissions can be represented using the following symbolic form:', + '', + ' u=rwx,g=rwx,o=rwx', + '', + ' where', + '', + ' - u: user permissions', + ' - g: group permissions', + ' - o: other/non-group permissions', + ' - r: read', + ' - w: write', + ' - x: execute' + ].join( '\n' ); + + actual = wrap( txt ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function wraps text with conditional bullet blocks', function test( t ) { + var expected; + var actual; + var txt; + + txt = [ + 'Applies a real elementary reflector `H = I - tau * v * v^T` to a real M by N matrix `C`.', + '', + 'If `side = \'left\'`,', + '', + '- `work` should have `N` indexed elements.', + '- `V` should have `1 + (M-1) * abs(strideV)` indexed elements.', + '- `C` is overwritten by `H * C`.', + '', + 'If `side = \'right\'`,', + '', + '- `work` should have `M` indexed elements.', + '- `V` should have `1 + (N-1) * abs(strideV)` indexed elements.', + '- `C` is overwritten by `C * H`.' + ].join( '\n' ); + + expected = [ + ' Applies a real elementary reflector `H = I - tau * v * v^T` to a real M by N', + ' matrix `C`.', + '', + ' If `side = \'left\'`,', + '', + ' - `work` should have `N` indexed elements.', + ' - `V` should have `1 + (M-1) * abs(strideV)` indexed elements.', + ' - `C` is overwritten by `H * C`.', + '', + ' If `side = \'right\'`,', + '', + ' - `work` should have `M` indexed elements.', + ' - `V` should have `1 + (N-1) * abs(strideV)` indexed elements.', + ' - `C` is overwritten by `C * H`.' + ].join( '\n' ); + + actual = wrap( txt ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +}); + +tape( 'the function wraps text with character-description bullet lists', function test( t ) { + var expected; + var actual; + var txt; + + txt = [ + 'Determines double-precision floating-point machine parameters.', + '', + 'The `cmach` parameter is a string which specifies the double-precision machine parameter to be returned. The function recognizes the following characters:', + '', + '- \'E\'/\'e\': (eps) relative machine precision.', + '- \'S\'/\'s\': (sfmin) safe minimum such that `1/sfmin` does not overflow.', + '- \'B\'/\'b\': (base) base of the machine (also known as the radix).', + '- \'P\'/\'p\': (prec) `eps*base`.', + '- \'N\'/\'n\': (t) number of (base) digits in the mantissa.', + '- \'R\'/\'r\': (rnd) `1.0` when rounding occurs in addition and `0.0` otherwise.' + ].join( '\n' ); + + expected = [ + ' Determines double-precision floating-point machine parameters.', + '', + ' The `cmach` parameter is a string which specifies the double-precision', + ' machine parameter to be returned. The function recognizes the following', + ' characters:', + '', + ' - \'E\'/\'e\': (eps) relative machine precision.', + ' - \'S\'/\'s\': (sfmin) safe minimum such that `1/sfmin` does not overflow.', + ' - \'B\'/\'b\': (base) base of the machine (also known as the radix).', + ' - \'P\'/\'p\': (prec) `eps*base`.', + ' - \'N\'/\'n\': (t) number of (base) digits in the mantissa.', + ' - \'R\'/\'r\': (rnd) `1.0` when rounding occurs in addition and `0.0` otherwise.' + ].join( '\n' ); + + actual = wrap( txt ); + + t.strictEqual( actual, expected, 'returns expected value' ); + t.end(); +});