Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* @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';

// VARIABLES //

var RE_PROSE_START = /^[a-zA-Z`(*'"[\u0080-￿]/;
var RE_NUMBERED = /^\d+\. /;


// MAIN //

/**
* Collapses continuation lines within prose paragraphs while preserving blank lines, sub-indented content, list items, and table rows.
*
* @private
* @param {string} text - text with indent already stripped
* @returns {string} text with continuation lines joined
*/
function collapseContinuations( text ) {
var current;
var parts;
var lines;
var line;
var i;

lines = text.split( '\n' );
parts = [];
current = [];
for ( i = 0; i < lines.length; i++ ) {
line = lines[ i ];
if (
line.length > 0 &&
RE_PROSE_START.test( line ) &&
!RE_NUMBERED.test( line )
) {
current.push( line );
} else {
if ( current.length > 0 ) {
parts.push( current.join( ' ' ) );
current = [];
}
parts.push( line );
}
}
if ( current.length > 0 ) {
parts.push( current.join( ' ' ) );
}
return parts.join( '\n' );
}


// EXPORTS //

module.exports = collapseContinuations;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @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';

/**
* Lint rule to detect premature line wrapping in `repl.txt` files.
*
* @module @stdlib/_tools/repl-txt/rules/no-premature-wrap
*
* @example
* var rule = require( '@stdlib/_tools/repl-txt/rules/no-premature-wrap' );
*
* console.log( rule );
*/

// MODULES //

var main = require( './main.js' );


// EXPORTS //

module.exports = main;
Original file line number Diff line number Diff line change
@@ -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 repeat = require( '@stdlib/string/repeat' );
var rtrim = require( '@stdlib/string/right-trim' );
var ltrim = require( '@stdlib/string/left-trim' );
var wrap = require( '@stdlib/_tools/repl-txt/wrap-text' );
var unwrap = require( './unwrap.js' );


// VARIABLES //

var MAX_WIDTH = 80;
var DESC_INDENT = 4;
var TAG_INDENT = 8;
var TAG_PREFIX = repeat( ' ', TAG_INDENT );
var DESC_OPTS = {
'indent': DESC_INDENT,
'maxWidth': MAX_WIDTH
};
var TAG_OPTS = {
'indent': TAG_INDENT,
'maxWidth': MAX_WIDTH
};


// FUNCTIONS //

/**
* Finds the first premature wrap by comparing original lines against rewrapped lines.
*
* @private
* @param {Array<string>} olines - original lines
* @param {Array<string>} rlines - rewrapped lines
* @returns {(Object|null)} object with `idx` and `extra` properties, or null
*/
function findPrematureWrap( olines, rlines ) {
var extra;
var i;

for ( i = 0; i < olines.length; i++ ) {
if ( olines[ i ] !== rlines[ i ] ) {
if ( rlines[ i ] && rlines[ i ].length > olines[ i ].length ) {
extra = ltrim( rlines[ i ].substring( olines[ i ].length ) );
if ( extra ) {
return {
'idx': i,
'extra': extra
};
}
}
return null;
}
}
return null;
}

/**
* Finds the line number where a tag description begins within a section.
*
* @private
* @param {Object} section - section node
* @param {Object} tag - tag object
* @returns {NonNegativeInteger} line number of the tag description start
*/
function findTagDescriptionLine( section, tag ) {
var firstLine;
var content;
var idx;

content = section.content;
firstLine = tag.description.split( '\n' )[ 0 ];
idx = content.indexOf( TAG_PREFIX + firstLine );
if ( idx < 0 ) {
return section.start;
}
return section.start + 2 + content.substring( 0, idx ).split( '\n' ).length;
}


// MAIN //

/**
* Rule for detecting premature line wrapping in the `repl.txt` files.
*
* @param {Context} context - lint context
* @returns {Object} validators
*/
function main( context ) {
/**
* Checks whether a description has premature line wrapping.
*
* @private
* @param {Object} description - description node
*/
function checkDescription( description ) {
var unwrapped;
var rewrapped;
var result;
var line;
var raw;

raw = rtrim( description.raw );
unwrapped = unwrap( raw, DESC_INDENT );
rewrapped = wrap( unwrapped, DESC_OPTS );
if ( rewrapped === raw ) {
return;
}
result = findPrematureWrap( raw.split( '\n' ), rewrapped.split( '\n' ) );
if ( result ) {
line = description.start + result.idx + 1;
context.report( '"' + result.extra + '" can fit on the previous line', {
'start': line,
'end': line
});
}
}

/**
* Checks whether tag descriptions have premature line wrapping.
*
* @private
* @param {Object} section - parameters or returns section
* @param {string} label - section label
*/
function checkTags( section, label ) {
var rewrappedLines;
var unwrapped;
var rewrapped;
var baseLine;
var olines;
var result;
var tags;
var line;
var i;

tags = section.tags;
if ( !tags ) {
return;
}
for ( i = 0; i < tags.length; i++ ) {
unwrapped = unwrap( TAG_PREFIX + tags[ i ].description, TAG_INDENT );

Check warning on line 161 in lib/node_modules/@stdlib/_tools/repl-txt/rules/no-premature-wrap/lib/main.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

This line has a length of 81. Maximum allowed is 80
rewrapped = wrap( unwrapped, TAG_OPTS );
rewrappedLines = rewrapped.split( '\n' );
rewrappedLines[ 0 ] = rewrappedLines[ 0 ].substring( TAG_OPTS.indent ); // eslint-disable-line max-len
olines = tags[ i ].description.split( '\n' );
result = findPrematureWrap( olines, rewrappedLines );
if ( result ) {
baseLine = findTagDescriptionLine( section, tags[ i ] );
line = baseLine + result.idx + 1;
context.report( 'In ' + label + ' "' + tags[ i ].name + '", "' + result.extra + '" can fit on the previous line', {
'start': line,
'end': line
});
}
}
}

/**
* Checks whether parameter tag descriptions have premature line wrapping.
*
* @private
* @param {Object} section - parameters section
*/
function checkParameters( section ) {
checkTags( section, 'parameter' );
}

/**
* Checks whether return tag descriptions have premature line wrapping.
*
* @private
* @param {Object} section - returns section
*/
function checkReturns( section ) {
checkTags( section, 'return' );
}

return {
'description': checkDescription,
'parameters': checkParameters,
'returns': checkReturns
};
}


// EXPORTS //

module.exports = main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* @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 startsWith = require( '@stdlib/string/starts-with' );
var repeat = require( '@stdlib/string/repeat' );
var collapseContinuations = require( './collapse_continuations.js' );


// MAIN //

/**
* Un-wraps text by stripping a leading indent and collapsing continuation lines.
*
* @private
* @param {string} text - indented text
* @param {NonNegativeInteger} indent - number of leading spaces to strip
* @returns {string} un-wrapped text
*/
function unwrap( text, indent ) {
var prefix;
var lines;
var i;

prefix = repeat( ' ', indent );
lines = text.split( '\n' );
for ( i = 0; i < lines.length; i++ ) {
if ( startsWith( lines[ i ], prefix ) ) {
lines[ i ] = lines[ i ].substring( indent );
}
}
return collapseContinuations( lines.join( '\n' ) );
}


// EXPORTS //

module.exports = unwrap;
Loading
Loading