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..e746011bc2a3 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/bin/cli @@ -0,0 +1,96 @@ +#!/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 opts; + 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(); + + // 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 ], opts ) ); // 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(), opts ) ); // 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..e6e97eff8f1e --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/etc/cli_opts.json @@ -0,0 +1,18 @@ +{ + "boolean": [ + "help", + "version" + ], + "integer": [ + "indent", + "max-width" + ], + "alias": { + "help": [ + "h" + ], + "version": [ + "V" + ] + } +} 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..5aadf18b046f --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/examples/index.js @@ -0,0 +1,106 @@ +/** +* @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 ); +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 ); +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 ); +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/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..604bb9cee830 --- /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.' ); +* // 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..1822b467715e --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/lib/main.js @@ -0,0 +1,208 @@ +/** +* @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 format = require( '@stdlib/string/format' ); +var validate = require( './validate.js' ); +var BREAK_CLASSES = require( './break_classes.json' ); + + +// 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 {Array} array of break unit segments +*/ +function findBreakUnits( text ) { + var segments; + var start; + var prev; + var curr; + var len; + var i; + + len = text.length; + 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; +} + +/** +* 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 - 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 +* @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 +* var out = wrap( 'This is a short line.' ); +* // returns ' This is a short line.' +*/ +function wrap( text, options ) { + var contentWidth; + var output; + var prefix; + var lines; + var opts; + var line; + var err; + var i; + + opts = { + 'indent': 4, + 'maxWidth': 80 + }; + if ( arguments.length > 1 ) { + err = validate( opts, options ); + if ( err ) { + throw err; + } + } + 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', opts.maxWidth, 'indent', opts.indent ) ); + } + if ( text.length === 0 ) { + return ''; + } + prefix = repeat( ' ', opts.indent ); + lines = text.split( '\n' ); + output = []; + for ( i = 0; i < lines.length; i++ ) { + line = lines[ i ]; + if ( line.length === 0 ) { + output.push( '' ); + } else if ( line.charAt( 0 ) === ' ' || line.charAt( 0 ) === '\t' ) { + output.push( prefix + line ); + } else { + output.push( wrapLine( line, contentWidth, prefix ) ); + } + } + return output.join( '\n' ); +} + + +// EXPORTS // + +module.exports = wrap; 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/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..0b3dc743527e --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/repl-txt/wrap-text/test/test.js @@ -0,0 +1,565 @@ +/** +* @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 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 `indent` option 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 a `maxWidth` option 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; + 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 ); + + 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 ); + + 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 ); + + 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 ); + + 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 ); + + 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 ); + + 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, { + 'indent': 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, { + 'indent': 4, + 'maxWidth': 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 ); + + 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(); +}); 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..7f94e2fe515f --- /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 `indent` option 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 a `maxWidth` option 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, 'returns expected value' ); + t.strictEqual( opts.maxWidth, 80, 'returns expected value' ); + + 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, {}, 'returns expected value' ); + + t.end(); +});