diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/README.md b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/README.md new file mode 100644 index 000000000000..6299fa2d4901 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/README.md @@ -0,0 +1,182 @@ + + +# remark-lint-expected-html-sections + +> [remark][remark] plugin to lint expected HTML sections in README files according to stdlib conventions. + +
+ +This plugin checks for the presence of required HTML sections in README.md files, as defined in stdlib's documentation conventions. It ensures that each README contains the essential sections needed for comprehensive documentation, and that sections with special requirements (such as the C API section) contain their own required subsections. + +
+ + + +
+ +## Usage + +```javascript +var expectedSections = require( '@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections' ); +``` + +### expectedSections( \[options] ) + +Validates the presence of expected HTML sections in README files. + +```javascript +var remark = require( 'remark' ); + +remark().use( expectedSections ).process( '# README', done ); + +function done( error, file ) { + if ( error ) { + console.error( error ); + } +} +``` + +The plugin accepts the following `options`: + +- **schema**: schema for expected HTML sections. + +The default schema requires `usage`, `examples`, and `links` at the root level, and if a `c` section exists, it requires `usage` and `examples` subsections. + +To specify a custom schema, set the `schema` option. + +```javascript +var remark = require( 'remark' ); + +var customSchema = { + 'root': { + 'required': [ 'usage', 'examples', 'links', 'related' ], + 'optional': [ 'intro', 'notes', 'c', 'references' ] + } +}; +var opts = { + 'schema': customSchema +}; +remark().use( expectedSections, opts ).process( '# README', done ); + +function done( error, file ) { + if ( error ) { + console.error( error ); + } +} +``` + +
+ + + +
+ +## Notes + +- The plugin detects HTML sections using pattern matching for `
` tags. +- The plugin builds a hierarchical model of the document structure to validate both root and nested sections. +- Missing required sections will generate lint errors with specific details about which sections are missing. + +
+ + + +
+ +## Examples + +```javascript +var remark = require( 'remark' ); +var expectedSections = require( '@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections' ); + +var lines = [ + '# Example Package', + '', + '
', + '', + '## Introduction', + '', + 'This is an example package.', + '', + '
', + '', + '', + '', + '
', + '', + '## Examples', + '', + '```javascript', + 'var example = require( \'example\' );', + 'example();', + '```', + '', + '
', + '', + '', + '', + '', + '', + '' +]; + +var source = lines.join( '\n' ); + +// Define default options: +var opts = { + 'schema': { + 'root': { + 'required': [ 'usage', 'examples', 'links' ], + 'optional': [ 'intro', 'notes', 'c', 'references', 'related' ] + } + } +}; + +// Process source with linter: +remark().use( expectedSections, opts ).process( source, done ); + +function done( error, file ) { + var i; + if ( error ) { + console.error( error ); + return; + } + if ( file.messages.length === 0 ) { + console.log( 'No lint errors found.' ); + } else { + for ( i = 0; i < file.messages.length; i++ ) { + console.log( '%d. %s', i+1, file.messages[ i ].reason ); + } + } +} +``` + +
+ + + + + + diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/examples/index.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/examples/index.js new file mode 100644 index 000000000000..ffb80e1abece --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/examples/index.js @@ -0,0 +1,83 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 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 remark = require( 'remark' ); +var expectedSections = require( './../lib' ); + +var lines = [ + '# Example Package', + '', + '
', + '', + '## Introduction', + '', + 'This is an example package.', + '', + '
', + '', + '', + '', + '
', + '', + '## Examples', + '', + '```javascript', + 'var example = require( \'example\' );', + 'example();', + '```', + '', + '
', + '', + '', + '', + '', + '', + '' +]; + +var source = lines.join( '\n' ); + +// Define default options: +var opts = { + 'schema': { + 'root': { + 'required': [ 'usage', 'examples', 'links' ], + 'optional': [ 'intro', 'notes', 'c', 'references', 'related' ] + } + } +}; + +// Process source with linter: +remark().use( expectedSections, opts ).process( source, done ); + +function done( error, file ) { + var i; + if ( error ) { + console.error( error ); + return; + } + if ( file.messages.length === 0 ) { + console.log( 'No lint errors found.' ); + } else { + for ( i = 0; i < file.messages.length; i++ ) { + console.log( '%d. %s', i+1, file.messages[ i ].reason ); + } + } +} diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/attacher.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/attacher.js new file mode 100644 index 000000000000..0c37b96f3f45 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/attacher.js @@ -0,0 +1,90 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 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 copy = require( '@stdlib/utils/copy' ); +var defaults = require( './defaults.json' ); +var validate = require( './validate.js' ); +var linter = require( './linter.js' ); + + +// MAIN // + +/** +* Attaches a plugin to a remark processor to lint expected HTML sections. +* +* @param {Options} [options] - plugin options +* @param {Object} [options.schema] - schema for expected HTML sections +* @throws {TypeError} options argument must be an object +* @throws {TypeError} must provide valid options +* @returns {Function} transform function +* +* @example +* var remark = require( 'remark' ); +* +* var str = [ +* '
', +* '', +* '## Usage', +* '', +* '
', +* '', +* '', +* '', +* '
', +* '', +* '## Examples', +* '', +* '
', +* '', +* '', +* '' +* ].join( '\n' ); +* +* remark().use( lint ).process( str, done ); +* +* function done( error ) { +* if ( error ) { +* throw error; +* } +* } +*/ +function attacher( options ) { + var opts; + var err; + + // Set default options: + opts = copy( defaults ); + + // NOTE: cannot use `arguments.length` check, as `options` may be explicitly passed as `undefined` + if ( options !== void 0 ) { + err = validate( opts, options ); + if ( err ) { + throw err; + } + } + return linter( opts ); +} + + +// EXPORTS // + +module.exports = attacher; diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/defaults.json b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/defaults.json new file mode 100644 index 000000000000..25ff7aabaf29 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/defaults.json @@ -0,0 +1,28 @@ +{ + "schema": { + "root": { + "required": [ + "usage", + "examples", + "links" + ], + "optional": [ + "intro", + "notes", + "c", + "references", + "related" + ] + }, + "c": { + "required": [ + "usage", + "examples" + ], + "optional": [ + "intro", + "notes" + ] + } + } +} diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/index.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/index.js new file mode 100644 index 000000000000..95c7e880236e --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 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'; + +/** +* remark lint plugin for validating HTML section hierarchy in README files. +* +* @module @stdlib/_tools/remark/plugins/remark-lint-expected-html-sections +* +* @example +* var remark = require( 'remark' ); +* var expectedHtmlSections = require( '@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections' ); +* +* var linter = remark().use( expectedHtmlSections ); +*/ + +// MODULES // + +var attacher = require( './attacher.js' ); + + +// EXPORTS // + +module.exports = attacher; diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/linter.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/linter.js new file mode 100644 index 000000000000..14f247773256 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/linter.js @@ -0,0 +1,184 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 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 logger = require( 'debug' ); +var visit = require( 'unist-util-visit' ); +var keys = require( '@stdlib/utils/keys' ); + + +// VARIABLES // + +var debug = logger( 'remark-lint-expected-html-sections' ); +var RE_SECTION_START = //; +var RE_SECTION_END = /<\/section>/; + + +// MAIN // + +/** +* Returns a linter function. +* +* @private +* @param {Object} options - linter options +* @param {Object} [options.schema] - section schema defining required and optional sections +* @returns {Function} linter function +*/ +function factory( options ) { + return linter; + + /** + * Validates HTML section hierarchy in README files according to stdlib conventions. + * + * @private + * @param {Node} tree - abstract syntax tree (AST) + * @param {File} file - virtual file + * @returns {void} + */ + function linter( tree, file ) { + var requiredRootSections; + var requiredCSections; + var sectionStructure; + var sectionsFound; + var sectionStack; + var missingRoot; + var missingC; + var schema; + var msg; + var i; + + debug( 'Linting file: %s', file.path || '' ); + schema = options.schema; + + // Initialize section tracking: + sectionStack = []; + sectionStructure = []; + + // Keep track of sections at different levels: + sectionsFound = { + 'root': {}, + 'c': {} + }; + + // Visit all HTML nodes to build section structure: + visit( tree, 'html', visitor ); + + // Log all sections found for debugging: + debug( 'Root sections found: %j', keys( sectionsFound.root ) ); + if ( sectionsFound.root.c ) { + debug( 'C sections found: %j', keys( sectionsFound.c ) ); + } + + // After visiting all nodes, validate against schema: + requiredRootSections = schema.root.required || []; + + // Check for missing required root sections: + missingRoot = []; + for ( i = 0; i < requiredRootSections.length; i++ ) { + if ( !sectionsFound.root[ requiredRootSections[ i ] ] ) { + missingRoot.push( requiredRootSections[ i ] ); + } + } + + if ( missingRoot.length > 0 ) { + msg = 'Missing required root-level sections: `' + missingRoot.join( '`, `' ) + '`. Required sections are: `' + requiredRootSections.join( '`, `' ) + '`. missing-required-sections'; + debug( msg ); + file.message( msg, tree ); + } + + // If 'c' section exists, check its requirements: + if ( sectionsFound.root.c ) { + requiredCSections = ( schema.c ) ? ( schema.c.required || [] ) : []; + + // Check for missing required C sections: + missingC = []; + for ( i = 0; i < requiredCSections.length; i++ ) { + if ( !sectionsFound.c[ requiredCSections[ i ] ] ) { + missingC.push( requiredCSections[ i ] ); + } + } + + if ( missingC.length > 0 ) { + msg = 'Missing required sections in "c" section: `' + missingC.join( '`, `' ) + '`. Required C sections are: `' + requiredCSections.join( '`, `' ) + '`. missing-required-c-sections'; + debug( msg ); + file.message( msg, sectionsFound.root.c.node ); + } + } + + debug( 'Finished linting: %s', file.path || '' ); + + /** + * Callback invoked upon finding a matching node. + * + * @private + * @param {Object} node - AST node + * @returns {void} + */ + function visitor( node ) { + var currentSection; + var sectionMatch; + var className; + + // Check if this is a section start tag: + sectionMatch = RE_SECTION_START.exec( node.value ); + if ( sectionMatch ) { + className = sectionMatch[ 1 ] || ''; + + debug( 'Found section with class: %s', className ); + + // Create section data object: + currentSection = { + 'node': node, + 'name': className, + 'children': [], + 'parent': null + }; + + // Add to parent if there is one: + if ( sectionStack.length > 0 ) { + currentSection.parent = sectionStack[ sectionStack.length - 1 ]; + currentSection.parent.children.push( currentSection ); + + // Record C-level section: + if ( currentSection.parent.name === 'c' ) { + sectionsFound.c[ className ] = currentSection; + } + } else { + // This is a root section: + sectionStructure.push( currentSection ); + sectionsFound.root[ className ] = currentSection; + } + + // Push to stack: + sectionStack.push( currentSection ); + } + // Check if this is a section end tag: + else if ( RE_SECTION_END.test( node.value ) && sectionStack.length > 0 ) { + sectionStack.pop(); + } + } + } +} + + +// EXPORTS // + +module.exports = factory; diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/validate.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/validate.js new file mode 100644 index 000000000000..e00e808c013e --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/validate.js @@ -0,0 +1,122 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 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 objectKeys = require( '@stdlib/utils/keys' ); +var isPlainObject = require( '@stdlib/assert/is-plain-object' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var isEmptyArray = require( '@stdlib/assert/is-empty-array' ); +var format = require( '@stdlib/string/format' ); + + +// FUNCTIONS // + +/** +* Validates a schema object. +* +* @private +* @param {Object} schema - schema object +* @returns {(Error|null)} null or an error object +*/ +function validateSchema( schema ) { + var section; + var keys; + var obj; + var i; + + keys = objectKeys( schema ); + for ( i = 0; i < keys.length; i++ ) { + section = keys[ i ]; + obj = schema[ section ]; + if ( !isPlainObject( obj ) ) { + return new TypeError( format( 'invalid option. `%s` option must be an object containing properties having values which are objects. Option: `%s`.', 'schema', JSON.stringify( obj ) ) ); + } + if ( hasOwnProp( obj, 'required' ) ) { + if ( !isStringArray( obj.required ) && !isEmptyArray( obj.required ) ) { + return new TypeError( format( 'invalid option. `%s` option must be an object having %s `%s` property which is an array of strings. Option: `%s`.', 'schema', 'a', section+'.required', JSON.stringify( obj ) ) ); + } + } else { + return new TypeError( format( 'invalid option. `%s` option must be an object having %s `%s` property which is an array of strings. Option: `%s`.', 'schema', 'a', section+'.required', JSON.stringify( obj ) ) ); + } + if ( hasOwnProp( obj, 'optional' ) ) { + if ( !isStringArray( obj.optional ) && !isEmptyArray( obj.optional ) ) { + return new TypeError( format( 'invalid option. `%s` option must be an object having %s `%s` property which is an array of strings. Option: `%s`.', 'schema', 'a', section+'.optional', JSON.stringify( obj ) ) ); + } + } else { + return new TypeError( format( 'invalid option. `%s` option must be an object having %s `%s` property which is an array of strings. Option: `%s`.', 'schema', 'a', section+'.optional', JSON.stringify( obj ) ) ); + } + } + return null; +} + + +// MAIN // + +/** +* Validates function options. +* +* @private +* @param {Object} opts - destination object +* @param {Options} options - function options +* @param {Object} [options.schema] - schema for expected HTML sections +* @returns {(Error|null)} null or an error object +* +* @example +* var opts = {}; +* var options = { +* 'schema': { +* 'root': { +* 'required': [ 'usage', 'examples', 'links' ], +* 'optional': [ 'intro', 'notes', 'c', 'references', 'related' ] +* } +* } +* }; +* var err = validate( opts, options ); +* if ( err ) { +* throw err; +* } +*/ +function validate( opts, options ) { + var err; + if ( !isPlainObject( options ) ) { + return new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) ); + } + if ( hasOwnProp( options, 'schema' ) ) { + if ( !isPlainObject( options.schema ) ) { + return new TypeError( format( 'invalid option. `%s` option must be an object. Option: `%s`.', 'schema', options.schema ) ); + } + if ( !hasOwnProp( options.schema, 'root' ) ) { + return new TypeError( format( 'invalid option. `%s` option must have %s `%s` property.', 'schema', 'a', 'root' ) ); + } + err = validateSchema( options.schema ); + if ( err ) { + return err; + } + opts.schema = options.schema; + } + return null; +} + + +// EXPORTS // + +module.exports = validate; diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/package.json b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/package.json new file mode 100644 index 000000000000..bac6cb9faa50 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/package.json @@ -0,0 +1,54 @@ +{ + "name": "@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections", + "version": "0.0.0", + "description": "remark lint plugin for validating expected HTML sections in README files according to stdlib conventions.", + "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" + } + ], + "main": "./lib", + "directories": { + "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": ">=6.0.0", + "npm": ">2.7.0" + }, + "keywords": [ + "stdlib", + "tools", + "lint", + "linter", + "markdown", + "md", + "remark", + "remark-plugin", + "plugin", + "html", + "section", + "structure", + "hierarchy", + "expected", + "validate" + ] +} diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/incomplete_c.md.txt b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/incomplete_c.md.txt new file mode 100644 index 000000000000..e3e0e13299fe --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/incomplete_c.md.txt @@ -0,0 +1,67 @@ +# Example + +
+ +## Introduction + +This is an introduction. + +
+ + + +
+ +## Usage + +```javascript +var foo = require( 'foo' ); +``` + +
+ + + +
+ +## Examples + +```javascript +var foo = require( 'foo' ); +foo(); +``` + +
+ + + +
+ +## C APIs + +
+ +### Introduction + +This section contains C API documentation. + +
+ + + + + + + +
+ + + + + + diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/invalid_asin.md.txt b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/invalid_asin.md.txt new file mode 100644 index 000000000000..f18826250dda --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/invalid_asin.md.txt @@ -0,0 +1,194 @@ + + +# asin + +> Compute the [arcsine][arcsine] of a double-precision floating-point number. + +
+ +## Usage + +```javascript +var asin = require( '@stdlib/math/base/special/asin' ); +``` + +#### asin( x ) + +Computes the [arcsine][arcsine] of a double-precision floating-point number (in radians). + +```javascript +var v = asin( 0.0 ); +// returns 0.0 + +v = asin( -3.141592653589793/6.0 ); +// returns ~-0.551 +``` + +The domain of `x` is restricted to `[-1,1]`. If `|x| > 1`, the function returns `NaN`. + +```javascript +var v = asin( -3.14 ); +// returns NaN +``` + +
+ + + +
+ +## Examples + + + +```javascript +var linspace = require( '@stdlib/array/base/linspace' ); +var asin = require( '@stdlib/math/base/special/asin' ); + +var x = linspace( -1.0, 1.0, 100 ); + +var i; +for ( i = 0; i < x.length; i++ ) { + console.log( asin( x[ i ] ) ); +} +``` + +
+ + + + + +* * * + +
+ +## C APIs + + + +
+ +
+ + + + + +### Usage + +```c +#include "stdlib/math/base/special/asin.h" +``` + +#### stdlib_base_asin( x ) + +Computes the [arcsine][arcsine] of a double-precision floating-point number (in radians). + +```c +double out = stdlib_base_asin( 0.0 ); +// returns 0.0 + +out = stdlib_base_asin( -3.141592653589793/6.0 ); +// returns ~-0.551 +``` + +The function accepts the following arguments: + +- **x**: `[in] double` input value (in radians). + +```c +double stdlib_base_asin( const double x ); +``` + + + +
+ +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/math/base/special/asin.h" +#include + +int main( void ) { + const double x[] = { -1.0, -0.78, -0.56, -0.33, -0.11, 0.11, 0.33, 0.56, 0.78, 1.0 }; + + double v; + int i; + for ( i = 0; i < 10; i++ ) { + v = stdlib_base_asin( x[ i ] ); + printf( "asin(%lf) = %lf\n", x[ i ], v ); + } +} +``` + +
+ + + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/missing_required_root.md.txt b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/missing_required_root.md.txt new file mode 100644 index 000000000000..ad1d31c5a8a6 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/missing_required_root.md.txt @@ -0,0 +1,35 @@ +# Example + +
+ +## Introduction + +This is an introduction. + +
+ + + + + +
+ +## Examples + +```javascript +var foo = require( 'foo' ); +foo(); +``` + +
+ + + + + + diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_asin.md.txt b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_asin.md.txt new file mode 100644 index 000000000000..4c73653603f0 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_asin.md.txt @@ -0,0 +1,200 @@ + + +# asin + +> Compute the [arcsine][arcsine] of a double-precision floating-point number. + +
+ +## Usage + +```javascript +var asin = require( '@stdlib/math/base/special/asin' ); +``` + +#### asin( x ) + +Computes the [arcsine][arcsine] of a double-precision floating-point number (in radians). + +```javascript +var v = asin( 0.0 ); +// returns 0.0 + +v = asin( -3.141592653589793/6.0 ); +// returns ~-0.551 +``` + +The domain of `x` is restricted to `[-1,1]`. If `|x| > 1`, the function returns `NaN`. + +```javascript +var v = asin( -3.14 ); +// returns NaN +``` + +
+ + + +
+ +## Examples + + + +```javascript +var linspace = require( '@stdlib/array/base/linspace' ); +var asin = require( '@stdlib/math/base/special/asin' ); + +var x = linspace( -1.0, 1.0, 100 ); + +var i; +for ( i = 0; i < x.length; i++ ) { + console.log( asin( x[ i ] ) ); +} +``` + +
+ + + + + +* * * + +
+ +## C APIs + + + +
+ +
+ + + + + +
+ +### Usage + +```c +#include "stdlib/math/base/special/asin.h" +``` + +#### stdlib_base_asin( x ) + +Computes the [arcsine][arcsine] of a double-precision floating-point number (in radians). + +```c +double out = stdlib_base_asin( 0.0 ); +// returns 0.0 + +out = stdlib_base_asin( -3.141592653589793/6.0 ); +// returns ~-0.551 +``` + +The function accepts the following arguments: + +- **x**: `[in] double` input value (in radians). + +```c +double stdlib_base_asin( const double x ); +``` + +
+ + + + + +
+ +
+ + + + + +
+ +### Examples + +```c +#include "stdlib/math/base/special/asin.h" +#include + +int main( void ) { + const double x[] = { -1.0, -0.78, -0.56, -0.33, -0.11, 0.11, 0.33, 0.56, 0.78, 1.0 }; + + double v; + int i; + for ( i = 0; i < 10; i++ ) { + v = stdlib_base_asin( x[ i ] ); + printf( "asin(%lf) = %lf\n", x[ i ], v ); + } +} +``` + +
+ + + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_complete.md.txt b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_complete.md.txt new file mode 100644 index 000000000000..06301206be7a --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_complete.md.txt @@ -0,0 +1,130 @@ +# Example + +
+ +## Introduction + +This is an introduction. + +
+ + + +
+ +## Usage + +```javascript +var foo = require( 'foo' ); +``` + +
+ + + +
+ +## Notes + +Some notes here. + +
+ + + +
+ +## Examples + +```javascript +var foo = require( 'foo' ); +foo(); +``` + +
+ + + +
+ +## C APIs + +
+ +### Introduction + +This section contains C API documentation. + +
+ + + +
+ +### Usage + +```c +#include "foo.h" +``` + +
+ + + +
+ +### Notes + +Some implementation notes... + +
+ + + +
+ +### Examples + +```c +// C example +#include "foo.h" +``` + +
+ + + +
+ + + +
+ +## References + +* Reference 1 +* Reference 2 + +
+ + + + + + + + + + diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_memoize.md.txt b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_memoize.md.txt new file mode 100644 index 000000000000..93357d7864a0 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/fixtures/valid_memoize.md.txt @@ -0,0 +1,212 @@ + + +# memoize + +> Memoize a function. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var memoize = require( '@stdlib/utils/memoize' ); +``` + +#### memoize( fcn\[, hashFunction] ) + +Memoizes a function. + +```javascript +var randu = require( '@stdlib/random/base/randu' ); + +function rand( n ) { + return n * randu(); +} + +var memoized = memoize( rand ); + +var v1 = memoized( 5 ); +var v2 = memoized( 5 ); + +var bool = ( v1 === v2 ); +// returns true +``` + +By default, the implementation serializes provided arguments as a `string` and stores results using the `string` as an identifier. To use a custom hash function, provide a hash function argument. + +```javascript +function add( obj ) { + return obj.x + obj.y + obj.z; +} + +obj = { + 'x': 3, + 'y': 4, + 'z': 5 +}; + +// Default behavior... + +var memoized = memoize( add ); + +var v1 = memoized( obj ); +// returns 12 + +var str = obj.toString(); +// returns '[object Object]' + +var v2 = memoized.cache[ str ]; +// returns 12 + +obj.x = 1000; + +var v3 = memoized( obj ); +// returns 12 + +// Custom hash function... + +function hashFunction( args ) { + return JSON.stringify( args ); +} + +memoized = memoize( add, hashFunction ); + +v1 = memoized( obj ); +// returns 1009 + +str = hashFunction( [ obj ] ); +// returns '[{"x":1000,"y":4,"z":5}]' + +v2 = memoized.cache[ str ]; +// returns 1009 + +obj.x = 6; + +v3 = memoized( obj ); +// returns 15 +``` + +#### memoized.cache + +Results cache. Note that, while the property is **read-only**, cache contents may be modified independently of the memoized function. + +```javascript +function beep( x ) { + throw new Error( 'boop' ); +} + +var memoized = memoize( beep ); + +var cache = memoized.cache; +// returns {} + +// Modify the cache: +cache[ 'bop' ] = 'bip'; + +var str = memoized( 'bop' ); +// returns 'bip' +``` + +
+ + + + + +
+ +## Notes + +- The implementation does **not** set the `length` of the returned function. Accordingly, the returned function `length` is **always** `0`. +- The evaluation context is **always** `null`. + +
+ + + + + +
+ +## Examples + + + +```javascript +var randu = require( '@stdlib/random/base/randu' ); +var floor = require( '@stdlib/math/base/special/floor' ); +var memoize = require( '@stdlib/utils/memoize' ); + +var fcn; +var n; +var v; +var i; + +function rand( n ) { + return n * randu(); +} + +fcn = memoize( rand ); + +for ( i = 0; i < 100; i++ ) { + n = floor( randu() * 5 ); + v = fcn( n ); + console.log( 'rand(%d) = %d', n, v ); +} +``` + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/test.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/test.js new file mode 100644 index 000000000000..8b68056d25e3 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/test.js @@ -0,0 +1,169 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 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 join = require( 'path' ).join; +var tape = require( 'tape' ); +var remark = require( 'remark' ); +var readFileSync = require( '@stdlib/fs/read-file' ).sync; +var contains = require( '@stdlib/assert/contains' ); +var expectedSections = require( './../lib' ); + + +// VARIABLES // + +var TEST_FIXTURES = join( __dirname, 'fixtures' ); +var CUSTOM_SCHEMA = { + 'root': { + 'required': [ 'usage', 'examples', 'links', 'related' ], + 'optional': [ 'intro', 'notes', 'c', 'references' ] + } +}; +var opts = { + 'encoding': 'utf8' +}; +var FIXTURE_VALID_COMPLETE = readFileSync( join( TEST_FIXTURES, 'valid_complete.md.txt' ), opts ); +var FIXTURE_VALID_MEMOIZE = readFileSync( join( TEST_FIXTURES, 'valid_memoize.md.txt' ), opts ); +var FIXTURE_VALID_ASIN = readFileSync( join( TEST_FIXTURES, 'valid_asin.md.txt' ), opts ); +var FIXTURE_INVALID_ASIN = readFileSync( join( TEST_FIXTURES, 'invalid_asin.md.txt' ), opts ); +var FIXTURE_MISSING_ROOT = readFileSync( join( TEST_FIXTURES, 'missing_required_root.md.txt' ), opts ); +var FIXTURE_INCOMPLETE_C = readFileSync( join( TEST_FIXTURES, 'incomplete_c.md.txt' ), opts ); + + +// FUNCTIONS // + +function lint( text, options, clbk ) { + remark().use( expectedSections, options ).process( text, clbk ); +} + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof expectedSections, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function validates a valid Markdown file containing all sections (default schema)', function test( t ) { + lint( FIXTURE_VALID_COMPLETE, {}, done ); + + function done( err, file ) { + if ( err ) { + t.fail( err.message ); + } + t.strictEqual( file.messages.length, 0, 'returns expected value' ); + t.end(); + } +}); + +tape( 'the function validates a valid Markdown file which does not contain C sections (default schema)', function test( t ) { + lint( FIXTURE_VALID_MEMOIZE, {}, done ); + + function done( err, file ) { + if ( err ) { + t.fail( err.message ); + } + t.strictEqual( file.messages.length, 0, 'returns expected value' ); + t.end(); + } +}); + +tape( 'the function validates a valid Markdown file containing C sections (default schema)', function test( t ) { + lint( FIXTURE_VALID_ASIN, {}, done ); + + function done( err, file ) { + if ( err ) { + t.fail( err.message ); + } + t.strictEqual( file.messages.length, 0, 'returns expected value' ); + t.end(); + } +}); + +tape( 'the function validates an invalid Markdown file missing a C section (default schema)', function test( t ) { + lint( FIXTURE_INVALID_ASIN, {}, done ); + + function done( err, file ) { + if ( err ) { + t.fail( err.message ); + } + t.strictEqual( file.messages.length, 1, 'returns expected value' ); + t.strictEqual( contains( file.messages[ 0 ].reason, 'Missing required sections in "c" section: `usage`' ), true, 'returns expected value' ); + t.end(); + } +}); + +tape( 'the function validates an invalid Markdown file missing required root sections (default schema)', function test( t ) { + lint( FIXTURE_MISSING_ROOT, {}, done ); + + function done( err, file ) { + if ( err ) { + t.fail( err.message ); + } + t.strictEqual( file.messages.length, 1, 'returns expected value' ); + t.strictEqual( contains( file.messages[ 0 ].reason, 'Missing required root-level sections: `usage`' ), true, 'returns expected value' ); + t.end(); + } +}); + +tape( 'the function validates an invalid Markdown file having an incomplete C section (default schema)', function test( t ) { + lint( FIXTURE_INCOMPLETE_C, {}, done ); + + function done( err, file ) { + if ( err ) { + t.fail( err.message ); + } + t.strictEqual( file.messages.length, 1, 'returns expected value' ); + t.strictEqual( contains( file.messages[ 0 ].reason, 'Missing required sections in "c" section: `usage`, `examples`' ), true, 'returns expected value' ); + t.end(); + } +}); + +tape( 'the function validates a valid Markdown file containing all sections using a custom schema', function test( t ) { + lint( FIXTURE_VALID_COMPLETE, { + 'schema': CUSTOM_SCHEMA + }, done ); + + function done( err, file ) { + if ( err ) { + t.fail( err.message ); + } + t.strictEqual( file.messages.length, 0, 'returns expected value' ); + t.end(); + } +}); + +tape( 'the function validates an invalid Markdown file containing a missing root section using a custom schema', function test( t ) { + var opts = { + 'schema': CUSTOM_SCHEMA + }; + lint( FIXTURE_MISSING_ROOT, opts, done ); + + function done( err, file ) { + if ( err ) { + t.fail( err.message ); + } + t.strictEqual( file.messages.length, 1, 'returns expected value' ); + t.strictEqual( contains( file.messages[ 0 ].reason, 'usage' ) && contains( file.messages[ 0 ].reason, 'related' ), true, 'returns expected value' ); + t.end(); + } +}); diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/test.validate.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/test.validate.js new file mode 100644 index 000000000000..86c8b4a1ec87 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/test.validate.js @@ -0,0 +1,207 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 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, + true, + false, + void 0, + null, + NaN, + [], + 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 a `schema` option which is not an object', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + '5', + 5, + true, + false, + void 0, + null, + NaN, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = { + 'schema': 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 schema without a root section', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'schema': { + 'section': { + 'required': [ 'usage' ], + 'optional': [ 'notes' ] + } + } + }; + + err = validate( opts, options ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error' ); + + t.end(); +}); + +tape( 'the function returns an error if provided a schema with incorrect structure', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'schema': { + 'root': { + 'required': 'usage', // Should be an array + 'optional': [ 'notes' ] + } + } + }; + + err = validate( opts, options ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error' ); + + t.end(); +}); + +tape( 'the function returns an error if a schema section is missing the required property', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'schema': { + 'root': { + 'optional': [ 'notes' ] + } + } + }; + + err = validate( opts, options ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error' ); + + t.end(); +}); + +tape( 'the function returns an error if a schema section is missing the optional property', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'schema': { + 'root': { + 'required': [ 'usage' ] + } + } + }; + + err = validate( opts, options ); + t.strictEqual( err instanceof TypeError, true, 'returns a type error' ); + + t.end(); +}); + +tape( 'the function returns `null` if all options are valid', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'schema': { + 'root': { + 'required': [ 'usage', 'examples', 'links' ], + 'optional': [ 'intro', 'notes', 'c', 'references', 'related' ] + } + } + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, options, 'sets options' ); + + t.end(); +}); + +tape( 'the function will ignore unrecognized options', function test( t ) { + var options; + var opts; + var err; + + opts = {}; + options = { + 'beep': true, + 'boop': 'bop' + }; + + err = validate( opts, options ); + t.strictEqual( err, null, 'returns null' ); + t.deepEqual( opts, {}, 'ignores unrecognized options' ); + + t.end(); +});