Skip to content

Commit 200dba6

Browse files
committed
Add JSDoc based types
1 parent a5b0667 commit 200dba6

File tree

5 files changed

+149
-33
lines changed

5 files changed

+149
-33
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
coverage/
22
node_modules/
33
.DS_Store
4+
*.d.ts
45
*.log
56
yarn.lock

index.js

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
1-
import phrasing from 'mdast-util-to-markdown/lib/util/container-phrasing.js'
2-
import defaultInlineCode from 'mdast-util-to-markdown/lib/handle/inline-code.js'
1+
/**
2+
* @typedef {import('mdast').Table} Table
3+
* @typedef {import('mdast').TableRow} TableRow
4+
* @typedef {import('mdast').TableCell} TableCell
5+
* @typedef {import('mdast').InlineCode} InlineCode
6+
* @typedef {import('markdown-table').MarkdownTableOptions} MarkdownTableOptions
7+
* @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension
8+
* @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle
9+
* @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension
10+
* @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle
11+
* @typedef {import('mdast-util-to-markdown').Context} ToMarkdownContext
12+
*
13+
* @typedef Options
14+
* @property {boolean} [tableCellPadding=true]
15+
* @property {boolean} [tablePipeAlign=true]
16+
* @property {MarkdownTableOptions['stringLength']} [stringLength]
17+
*/
18+
19+
import {containerPhrasing} from 'mdast-util-to-markdown/lib/util/container-phrasing.js'
20+
import {inlineCode} from 'mdast-util-to-markdown/lib/handle/inline-code.js'
321
import {markdownTable} from 'markdown-table'
422

23+
/** @type {FromMarkdownExtension} */
524
export const gfmTableFromMarkdown = {
625
enter: {
726
table: enterTable,
@@ -18,30 +37,37 @@ export const gfmTableFromMarkdown = {
1837
}
1938
}
2039

40+
/** @type {FromMarkdownHandle} */
2141
function enterTable(token) {
42+
// @ts-expect-error: `align` is custom.
2243
this.enter({type: 'table', align: token._align, children: []}, token)
2344
this.setData('inTable', true)
2445
}
2546

47+
/** @type {FromMarkdownHandle} */
2648
function exitTable(token) {
2749
this.exit(token)
2850
this.setData('inTable')
2951
}
3052

53+
/** @type {FromMarkdownHandle} */
3154
function enterRow(token) {
3255
this.enter({type: 'tableRow', children: []}, token)
3356
}
3457

58+
/** @type {FromMarkdownHandle} */
3559
function exit(token) {
3660
this.exit(token)
3761
}
3862

63+
/** @type {FromMarkdownHandle} */
3964
function enterCell(token) {
4065
this.enter({type: 'tableCell', children: []}, token)
4166
}
4267

4368
// Overwrite the default code text data handler to unescape escaped pipes when
4469
// they are in tables.
70+
/** @type {FromMarkdownHandle} */
4571
function exitCodeText(token) {
4672
let value = this.resume()
4773

@@ -53,11 +79,20 @@ function exitCodeText(token) {
5379
this.exit(token)
5480
}
5581

82+
/**
83+
* @param {string} $0
84+
* @param {string} $1
85+
* @returns {string}
86+
*/
5687
function replace($0, $1) {
5788
// Pipes work, backslashes don’t (but can’t escape pipes).
5889
return $1 === '|' ? $1 : $0
5990
}
6091

92+
/**
93+
* @param {Options} [options]
94+
* @returns {ToMarkdownExtension}
95+
*/
6196
export function gfmTableToMarkdown(options) {
6297
const settings = options || {}
6398
const padding = settings.tableCellPadding
@@ -92,27 +127,48 @@ export function gfmTableToMarkdown(options) {
92127
}
93128
}
94129

130+
/**
131+
* @type {ToMarkdownHandle}
132+
* @param {Table} node
133+
*/
95134
function handleTable(node, _, context) {
135+
// @ts-expect-error: fixed in `markdown-table@3.0.1`.
96136
return serializeData(handleTableAsData(node, context), node.align)
97137
}
98138

99-
// This function isn’t really used normally, because we handle rows at the
100-
// table level.
101-
// But, if someone passes in a table row, this ensures we make somewhat sense.
139+
/**
140+
* This function isn’t really used normally, because we handle rows at the
141+
* table level.
142+
* But, if someone passes in a table row, this ensures we make somewhat sense.
143+
*
144+
* @type {ToMarkdownHandle}
145+
* @param {TableRow} node
146+
*/
102147
function handleTableRow(node, _, context) {
103148
const row = handleTableRowAsData(node, context)
104149
// `markdown-table` will always add an align row
105150
const value = serializeData([row])
106151
return value.slice(0, value.indexOf('\n'))
107152
}
108153

154+
/**
155+
* @type {ToMarkdownHandle}
156+
* @param {TableCell} node
157+
*/
109158
function handleTableCell(node, _, context) {
110159
const exit = context.enter('tableCell')
111-
const value = phrasing(node, context, {before: around, after: around})
160+
const value = containerPhrasing(node, context, {
161+
before: around,
162+
after: around
163+
})
112164
exit()
113165
return value
114166
}
115167

168+
/**
169+
* @param {Array.<Array.<string>>} matrix
170+
* @param {Array.<string>} [align]
171+
*/
116172
function serializeData(matrix, align) {
117173
return markdownTable(matrix, {
118174
align,
@@ -122,14 +178,18 @@ export function gfmTableToMarkdown(options) {
122178
})
123179
}
124180

181+
/**
182+
* @param {Table} node
183+
* @param {ToMarkdownContext} context
184+
*/
125185
function handleTableAsData(node, context) {
126186
const children = node.children
127187
let index = -1
128-
const length = children.length
188+
/** @type {Array.<Array.<string>>} */
129189
const result = []
130190
const subexit = context.enter('table')
131191

132-
while (++index < length) {
192+
while (++index < children.length) {
133193
result[index] = handleTableRowAsData(children[index], context)
134194
}
135195

@@ -138,14 +198,18 @@ export function gfmTableToMarkdown(options) {
138198
return result
139199
}
140200

201+
/**
202+
* @param {TableRow} node
203+
* @param {ToMarkdownContext} context
204+
*/
141205
function handleTableRowAsData(node, context) {
142206
const children = node.children
143207
let index = -1
144-
const length = children.length
208+
/** @type {Array.<string>} */
145209
const result = []
146210
const subexit = context.enter('tableRow')
147211

148-
while (++index < length) {
212+
while (++index < children.length) {
149213
result[index] = handleTableCell(children[index], node, context)
150214
}
151215

@@ -154,8 +218,12 @@ export function gfmTableToMarkdown(options) {
154218
return result
155219
}
156220

221+
/**
222+
* @type {ToMarkdownHandle}
223+
* @param {InlineCode} node
224+
*/
157225
function inlineCodeWithTable(node, parent, context) {
158-
let value = defaultInlineCode(node, parent, context)
226+
let value = inlineCode(node, parent, context)
159227

160228
if (context.stack.includes('tableCell')) {
161229
value = value.replace(/\|/g, '\\$&')

package.json

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,37 @@
3131
"sideEffects": false,
3232
"type": "module",
3333
"main": "index.js",
34+
"types": "index.d.ts",
3435
"files": [
36+
"index.d.ts",
3537
"index.js"
3638
],
3739
"dependencies": {
3840
"markdown-table": "^3.0.0",
39-
"mdast-util-to-markdown": "~0.6.0"
41+
"mdast-util-to-markdown": "^1.0.0"
4042
},
4143
"devDependencies": {
44+
"@types/tape": "^4.0.0",
4245
"c8": "^7.0.0",
43-
"mdast-util-from-markdown": "^0.8.0",
44-
"micromark-extension-gfm-table": "^0.4.0",
46+
"mdast-util-from-markdown": "^1.0.0",
47+
"micromark-extension-gfm-table": "^1.0.0",
4548
"prettier": "^2.0.0",
4649
"remark-cli": "^9.0.0",
4750
"remark-preset-wooorm": "^8.0.0",
51+
"rimraf": "^3.0.0",
4852
"string-width": "^5.0.0",
4953
"tape": "^5.0.0",
54+
"type-coverage": "^2.0.0",
55+
"typescript": "^4.0.0",
5056
"unist-util-remove-position": "^4.0.0",
5157
"xo": "^0.39.0"
5258
},
5359
"scripts": {
60+
"build": "rimraf \"*.d.ts\" && tsc && type-coverage",
5461
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
5562
"test-api": "node --conditions development test.js",
5663
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --conditions development test.js",
57-
"test": "npm run format && npm run test-coverage"
64+
"test": "npm run build && npm run format && npm run test-coverage"
5865
},
5966
"prettier": {
6067
"tabWidth": 2,
@@ -71,5 +78,11 @@
7178
"plugins": [
7279
"preset-wooorm"
7380
]
81+
},
82+
"typeCoverage": {
83+
"atLeast": 100,
84+
"detail": true,
85+
"strict": true,
86+
"ignoreCatch": true
7487
}
7588
}

test.js

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import test from 'tape'
22
import stringWidth from 'string-width'
3-
import fromMarkdown from 'mdast-util-from-markdown'
4-
import toMarkdown from 'mdast-util-to-markdown'
3+
import {fromMarkdown} from 'mdast-util-from-markdown'
4+
import {toMarkdown} from 'mdast-util-to-markdown'
55
import {removePosition} from 'unist-util-remove-position'
6-
import gfmTable from 'micromark-extension-gfm-table'
6+
import {gfmTable} from 'micromark-extension-gfm-table'
77
import {gfmTableFromMarkdown, gfmTableToMarkdown} from './index.js'
88

99
test('markdown -> mdast', (t) => {
@@ -67,15 +67,23 @@ test('markdown -> mdast', (t) => {
6767
mdastExtensions: [gfmTableFromMarkdown]
6868
}),
6969
true
70-
).children[0],
70+
),
7171
{
72-
type: 'table',
73-
align: [null],
72+
type: 'root',
7473
children: [
7574
{
76-
type: 'tableRow',
75+
type: 'table',
76+
align: [null],
7777
children: [
78-
{type: 'tableCell', children: [{type: 'inlineCode', value: '|'}]}
78+
{
79+
type: 'tableRow',
80+
children: [
81+
{
82+
type: 'tableCell',
83+
children: [{type: 'inlineCode', value: '|'}]
84+
}
85+
]
86+
}
7987
]
8088
}
8189
]
@@ -90,8 +98,13 @@ test('markdown -> mdast', (t) => {
9098
mdastExtensions: [gfmTableFromMarkdown]
9199
}),
92100
true
93-
).children[0],
94-
{type: 'paragraph', children: [{type: 'inlineCode', value: '\\|'}]},
101+
),
102+
{
103+
type: 'root',
104+
children: [
105+
{type: 'paragraph', children: [{type: 'inlineCode', value: '\\|'}]}
106+
]
107+
},
95108
'should not support an escaped pipe in code *not* in a table cell'
96109
)
97110

@@ -102,20 +115,25 @@ test('markdown -> mdast', (t) => {
102115
mdastExtensions: [gfmTableFromMarkdown]
103116
}),
104117
true
105-
).children[0],
118+
),
106119
{
107-
type: 'table',
108-
align: [null, null],
120+
type: 'root',
109121
children: [
110122
{
111-
type: 'tableRow',
123+
type: 'table',
124+
align: [null, null],
112125
children: [
113-
{type: 'tableCell', children: [{type: 'text', value: '`\\'}]},
114126
{
115-
type: 'tableCell',
127+
type: 'tableRow',
116128
children: [
117-
{type: 'inlineCode', value: '\\\\'},
118-
{type: 'text', value: ' b'}
129+
{type: 'tableCell', children: [{type: 'text', value: '`\\'}]},
130+
{
131+
type: 'tableCell',
132+
children: [
133+
{type: 'inlineCode', value: '\\\\'},
134+
{type: 'text', value: ' b'}
135+
]
136+
}
119137
]
120138
}
121139
]

tsconfig.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"include": ["*.js"],
3+
"compilerOptions": {
4+
"target": "ES2020",
5+
"lib": ["ES2020"],
6+
"module": "ES2020",
7+
"moduleResolution": "node",
8+
"allowJs": true,
9+
"checkJs": true,
10+
"declaration": true,
11+
"emitDeclarationOnly": true,
12+
"allowSyntheticDefaultImports": true,
13+
"skipLibCheck": true,
14+
"strict": true
15+
}
16+
}

0 commit comments

Comments
 (0)