Skip to content

Commit

Permalink
Add JSDoc based types
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Mar 18, 2021
1 parent f1a3411 commit 2666fd4
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,4 +1,5 @@
.DS_Store
*.d.ts
*.log
coverage/
node_modules/
Expand Down
65 changes: 53 additions & 12 deletions index.js
@@ -1,26 +1,56 @@
import repeat from 'repeat-string'

// Create a table from a matrix of strings.
/**
* @typedef MarkdownTableOptions
* @property {string|string[]} [align]
* @property {boolean} [padding=true]
* @property {boolean} [delimiterStart=true]
* @property {boolean} [delimiterStart=true]
* @property {boolean} [delimiterEnd=true]
* @property {boolean} [alignDelimiters=true]
* @property {(value: string) => number} [stringLength]
*/

/**
* Create a table from a matrix of strings.
*
* @param {string[][]} table
* @param {MarkdownTableOptions} [options]
* @returns {string}
*/
export function markdownTable(table, options) {
var settings = options || {}
var align = (settings.align || []).concat()
var stringLength = settings.stringLength || defaultStringLength
/** @type {number[]} Character codes as symbols for alignment per column. */
var alignments = []
var rowIndex = -1
/** @type {string[][]} Cells per row. */
var cellMatrix = []
/** @type {number[][]} Sizes of each cell per row. */
var sizeMatrix = []
/** @type {number[]} */
var longestCellByColumn = []
var mostCellsPerRow = 0
/** @type {number} */
var columnIndex
/** @type {string[]} Cells of current row */
var row
/** @type {number[]} Sizes of current row */
var sizes
var largest
/** @type {number} Sizes of current cell */
var size
/** @type {string} Current cell */
var cell
/** @type {string[]} */
var lines
/** @type {string[]} Chunks of current line. */
var line
/** @type {string} */
var before
/** @type {string} */
var after
/** @type {number} */
var code

// This is a superfluous loop if we don’t align delimiters, but otherwise we’d
Expand All @@ -41,9 +71,10 @@ export function markdownTable(table, options) {
size = stringLength(cell)
sizes[columnIndex] = size

largest = longestCellByColumn[columnIndex]

if (largest === undefined || size > largest) {
if (
longestCellByColumn[columnIndex] === undefined ||
size > longestCellByColumn[columnIndex]
) {
longestCellByColumn[columnIndex] = size
}
}
Expand Down Expand Up @@ -186,26 +217,36 @@ export function markdownTable(table, options) {
}
}

line = line.join('')

if (settings.delimiterEnd === false) {
line = line.replace(/ +$/, '')
}

lines.push(line)
lines.push(
settings.delimiterEnd === false
? line.join('').replace(/ +$/, '')
: line.join('')
)
}

return lines.join('\n')
}

/**
* @param {string|null|undefined} [value]
* @returns {string}
*/
function serialize(value) {
return value === null || value === undefined ? '' : String(value)
}

/**
* @param {string} value
* @returns {number}
*/
function defaultStringLength(value) {
return value.length
}

/**
* @param {string} value
* @returns {number}
*/
function toAlignment(value) {
var code = typeof value === 'string' ? value.charCodeAt(0) : 0

Expand Down
20 changes: 14 additions & 6 deletions package.json
Expand Up @@ -24,28 +24,37 @@
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/repeat-string": "^1.0.0",
"repeat-string": "^1.0.0"
},
"devDependencies": {
"@types/tape": "^4.0.0",
"c8": "^7.0.0",
"chalk": "^4.0.0",
"nyc": "^15.0.0",
"prettier": "^2.0.0",
"remark-cli": "^9.0.0",
"remark-preset-wooorm": "^8.0.0",
"rimraf": "^3.0.0",
"strip-ansi": "^6.0.0",
"tape": "^5.0.0",
"type-coverage": "^2.0.0",
"typescript": "^4.0.0",
"xo": "^0.38.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"*.d.ts\" && tsc && type-coverage",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node test.js",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",
"test": "npm run format && npm run test-coverage"
"test": "npm run build && npm run format && npm run test-coverage"
},
"remarkConfig": {
"plugins": [
Expand All @@ -68,10 +77,9 @@
"prefer-arrow-callback": "off"
}
},
"nyc": {
"check-coverage": true,
"lines": 100,
"functions": 100,
"branches": 100
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true
}
}
2 changes: 1 addition & 1 deletion readme.md
Expand Up @@ -81,7 +81,7 @@ Turns a given matrix of strings (an array of arrays of strings) into a table.
###### `options.align`

One style for all columns, or styles for their respective columns (`string` or
`Array.<string>`).
`string[]`).
Each style is either `'l'` (left), `'r'` (right), or `'c'` (center).
Other values are treated as `''`, which doesn’t place the colon in the alignment
row but does align left.
Expand Down
9 changes: 8 additions & 1 deletion test.js
Expand Up @@ -23,10 +23,13 @@ test('markdownTable()', function (t) {
markdownTable([
['Type', 'Value'],
['string', 'alpha'],
// @ts-ignore
['number', 1],
// @ts-ignore
['boolean', true],
['undefined', undefined],
['null', null],
// @ts-ignore
['Array', [1, 2, 3]]
]),
[
Expand Down Expand Up @@ -285,7 +288,11 @@ test('markdownTable()', function (t) {
t.end()
})

// Get the length of a string, minus ANSI color characters.
/**
* Get the length of a string, minus ANSI color characters.
* @param {string} value
* @returns {number}
*/
function stringLength(value) {
return strip(value).length
}
16 changes: 16 additions & 0 deletions tsconfig.json
@@ -0,0 +1,16 @@
{
"files": ["index.js"],
"include": ["*.js"],
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020"],
"module": "ES2020",
"moduleResolution": "node",
"allowJs": true,
"checkJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true
}
}

0 comments on commit 2666fd4

Please sign in to comment.