mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
151 lines
4.5 KiB
JavaScript
151 lines
4.5 KiB
JavaScript
/*
|
|
Copyright 2019 the JSDoc 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
|
|
|
|
https://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.
|
|
*/
|
|
import { flags } from './flags.js';
|
|
|
|
function padLeft(str, length) {
|
|
return str.padStart(str.length + length);
|
|
}
|
|
|
|
function padRight(str, length) {
|
|
return str.padEnd(str.length + length);
|
|
}
|
|
|
|
function findMaxLength(arr) {
|
|
let max = 0;
|
|
|
|
arr.forEach(({ length }) => {
|
|
max = Math.max(max, length);
|
|
});
|
|
|
|
return max;
|
|
}
|
|
|
|
function concatWithMaxLength(items, maxLength) {
|
|
let result = '';
|
|
|
|
// to prevent endless loops, always use the first item, regardless of length
|
|
result += items.shift();
|
|
|
|
while (items.length && result.length + items[0].length < maxLength) {
|
|
result += ` ${items.shift()}`;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Format the name and description of each flag into columns, similar to the following example,
|
|
* where the pipe (`|`) characters represent the start and end of the line:
|
|
*
|
|
* ```
|
|
* | -f, --foo Very long description very long description very long |
|
|
* | description very long description. |
|
|
* | --bar This description is not as long. |
|
|
* ```
|
|
*
|
|
* @param {Object} flagInfo - Information about each known flag.
|
|
* @param {Array<string>} flagInfo.names - An array of known flag names.
|
|
* @param {Array<string>} flagInfo.descriptions - An array of descriptions for each known flag, in
|
|
* the same order as `flagInfo.names`.
|
|
* @param {Object} opts - Options for formatting the text.
|
|
* @param {number} opts.maxLength - The maximum length of each line.
|
|
*/
|
|
function formatHelpInfo({ names, descriptions }, { maxLength }) {
|
|
const MARGIN_SIZE = 4;
|
|
const GUTTER_SIZE = MARGIN_SIZE;
|
|
const results = [];
|
|
|
|
const maxNameLength = findMaxLength(names);
|
|
const wrapDescriptionAt = maxLength - MARGIN_SIZE * 2 - GUTTER_SIZE - maxNameLength;
|
|
|
|
// Build the string for each flag.
|
|
names.forEach((name, i) => {
|
|
let result;
|
|
let partialDescription;
|
|
let words;
|
|
|
|
// Add some whitespace before the name.
|
|
result = padLeft(name, MARGIN_SIZE);
|
|
// Make the descriptions left-justified, with a gutter between the names and descriptions.
|
|
result = padRight(result, maxNameLength - name.length + GUTTER_SIZE);
|
|
|
|
// Split the description on spaces.
|
|
words = descriptions[i].split(' ');
|
|
// Add as much of the description as we can fit on the first line.
|
|
result += concatWithMaxLength(words, wrapDescriptionAt);
|
|
// If there's anything left, keep going until we've consumed the entire description.
|
|
while (words.length) {
|
|
// Add whitespace for the name column and the gutter.
|
|
partialDescription = padLeft('', MARGIN_SIZE + maxNameLength + GUTTER_SIZE);
|
|
partialDescription += concatWithMaxLength(words, wrapDescriptionAt);
|
|
result += `\n${partialDescription}`;
|
|
}
|
|
|
|
results.push(result);
|
|
});
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Get a formatted version of the help text for JSDoc.
|
|
*
|
|
* @alias module:@jsdoc/cli/lib/help
|
|
* @param {Object} opts - Options for formatting the help text.
|
|
* @param {number} opts.maxLength - The maximum length of each line in the formatted text.
|
|
* @return {string} The formatted help text.
|
|
* @private
|
|
*/
|
|
export default function help({ maxLength }) {
|
|
const flagInfo = {
|
|
names: [],
|
|
descriptions: [],
|
|
};
|
|
|
|
Object.keys(flags)
|
|
.sort()
|
|
.forEach((flagName) => {
|
|
const flagDetail = flags[flagName];
|
|
let description = '';
|
|
let name = '';
|
|
|
|
if (flagDetail.alias) {
|
|
name += `-${flagDetail.alias}, `;
|
|
}
|
|
|
|
name += `--${flagName}`;
|
|
|
|
if (flagDetail.requiresArg) {
|
|
name += ' <value>';
|
|
}
|
|
|
|
description += flagDetail.description;
|
|
|
|
if (flagDetail.array) {
|
|
description += ' Can be specified more than once.';
|
|
}
|
|
|
|
if (flagDetail.choices) {
|
|
description += ` Accepts these values: ${flagDetail.choices.join(', ')}`;
|
|
}
|
|
|
|
flagInfo.names.push(name);
|
|
flagInfo.descriptions.push(description);
|
|
});
|
|
|
|
return `${formatHelpInfo(flagInfo, { maxLength }).join('\n')}`;
|
|
}
|