markdown-magic 4.9.0 → 4.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -6
- package/src/transforms/index.js +12 -1
- package/src/utils/format-md.js +165 -12
- package/src/utils/format-md.test.js +175 -0
- package/types/src/cli-run.d.ts +1 -1
- package/types/src/globparse.d.ts +10 -10
- package/types/src/utils/format-md.d.ts +12 -0
- package/types/src/utils/format-md.d.ts.map +1 -1
- package/types/src/utils/fs.d.ts +1 -1
- package/types/_tests/config.d.ts +0 -4
- package/types/_tests/config.d.ts.map +0 -1
- package/types/_tests/errors.test.d.ts +0 -2
- package/types/_tests/errors.test.d.ts.map +0 -1
- package/types/_tests/fixtures/js/simple.d.ts +0 -8
- package/types/_tests/fixtures/js/simple.d.ts.map +0 -1
- package/types/_tests/fixtures/local-code-file-lines.d.ts +0 -1
- package/types/_tests/fixtures/local-code-file-lines.d.ts.map +0 -1
- package/types/_tests/fixtures/local-code-file.d.ts +0 -2
- package/types/_tests/fixtures/local-code-file.d.ts.map +0 -1
- package/types/_tests/fixtures/local-code-id.d.ts +0 -3
- package/types/_tests/fixtures/local-code-id.d.ts.map +0 -1
- package/types/_tests/transforms-toc.test.d.ts +0 -2
- package/types/_tests/transforms-toc.test.d.ts.map +0 -1
- package/types/_tests/transforms.test.d.ts +0 -2
- package/types/_tests/transforms.test.d.ts.map +0 -1
- package/types/_tests/utils/diff.d.ts +0 -3
- package/types/_tests/utils/diff.d.ts.map +0 -1
- package/types/src/argparse/argparse.test.d.ts +0 -2
- package/types/src/argparse/argparse.test.d.ts.map +0 -1
- package/types/src/argparse/splitOutsideQuotes.test.d.ts +0 -2
- package/types/src/argparse/splitOutsideQuotes.test.d.ts.map +0 -1
- package/types/src/cli-run.test.d.ts +0 -2
- package/types/src/cli-run.test.d.ts.map +0 -1
- package/types/src/globparse.test.d.ts +0 -2
- package/types/src/globparse.test.d.ts.map +0 -1
- package/types/src/index.test.d.ts +0 -2
- package/types/src/index.test.d.ts.map +0 -1
- package/types/src/transforms/code/resolve-github-file.test.d.ts +0 -2
- package/types/src/transforms/code/resolve-github-file.test.d.ts.map +0 -1
- package/types/src/utils/fs.test.d.ts +0 -2
- package/types/src/utils/fs.test.d.ts.map +0 -1
- package/types/src/utils/text.test.d.ts +0 -2
- package/types/src/utils/text.test.d.ts.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdown-magic",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.3",
|
|
4
4
|
"description": "Automatically update markdown files with content from external sources",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
"url": "https://github.com/DavidWells/markdown-magic"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@davidwells/dx-args": "0.2.
|
|
43
|
+
"@davidwells/dx-args": "0.2.1",
|
|
44
44
|
"@davidwells/md-utils": "0.0.53",
|
|
45
45
|
"color-convert": "^2.0.1",
|
|
46
|
-
"comment-block-parser": "1.6.
|
|
47
|
-
"comment-block-replacer": "0.1.
|
|
48
|
-
"comment-block-transformer": "0.8.
|
|
46
|
+
"comment-block-parser": "1.6.4",
|
|
47
|
+
"comment-block-replacer": "0.1.23",
|
|
48
|
+
"comment-block-transformer": "0.8.4",
|
|
49
49
|
"globrex": "^0.1.2",
|
|
50
50
|
"gray-matter": "^4.0.3",
|
|
51
51
|
"is-glob": "^4.0.3",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "af6399c4247586b9c8c74cd09327b842ebf5a9c2"
|
|
74
74
|
}
|
package/src/transforms/index.js
CHANGED
|
@@ -74,6 +74,11 @@ const transforms = {
|
|
|
74
74
|
*
|
|
75
75
|
* **Options:**
|
|
76
76
|
* - `src`: The relative path to the file to pull in
|
|
77
|
+
* - `sections`: Comma-separated list or array of markdown section headings to include
|
|
78
|
+
* - `section`: Single markdown section heading to include
|
|
79
|
+
* - `headings`: Array of markdown heading levels to include, such as `headings={[2,3]}`
|
|
80
|
+
* - `removeLeadingH1`: Remove the first H1 from imported markdown
|
|
81
|
+
* - `shiftHeaders`: Shift imported markdown headings up or down by a number
|
|
77
82
|
*
|
|
78
83
|
* **Example:**
|
|
79
84
|
* ```md
|
|
@@ -97,6 +102,12 @@ const transforms = {
|
|
|
97
102
|
*
|
|
98
103
|
* **Options:**
|
|
99
104
|
* - `url`: The URL of the remote content to pull in
|
|
105
|
+
* - `src`: Alias for `url`
|
|
106
|
+
* - `sections`: Comma-separated list or array of markdown section headings to include
|
|
107
|
+
* - `section`: Single markdown section heading to include
|
|
108
|
+
* - `headings`: Array of markdown heading levels to include, such as `headings={[2,3]}`
|
|
109
|
+
* - `removeLeadingH1`: Remove the first H1 from imported markdown
|
|
110
|
+
* - `shiftHeaders`: Shift imported markdown headings up or down by a number
|
|
100
111
|
*
|
|
101
112
|
* **Example:**
|
|
102
113
|
* ```md
|
|
@@ -208,4 +219,4 @@ const transforms = {
|
|
|
208
219
|
install: install,
|
|
209
220
|
}
|
|
210
221
|
|
|
211
|
-
module.exports = transforms
|
|
222
|
+
module.exports = transforms
|
package/src/utils/format-md.js
CHANGED
|
@@ -3,6 +3,17 @@ const { removeLeadingH1 } = require('@davidwells/md-utils/string-utils')
|
|
|
3
3
|
|
|
4
4
|
function formatMd(content, options = {}) {
|
|
5
5
|
let fileContents = content
|
|
6
|
+
|
|
7
|
+
/* automatically trim frontmatter if file is markdown */
|
|
8
|
+
if (options.trimFrontmatter !== false) {
|
|
9
|
+
const frontmatter = findFrontmatter(fileContents)
|
|
10
|
+
if (frontmatter && frontmatter.frontMatterRaw) {
|
|
11
|
+
fileContents = fileContents.replace(frontmatter.frontMatterRaw, '')
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
fileContents = selectMarkdownSections(fileContents, options)
|
|
16
|
+
|
|
6
17
|
if (options.removeLeadingH1 || options.stripFirstH1) {
|
|
7
18
|
fileContents = removeLeadingH1(fileContents)
|
|
8
19
|
}
|
|
@@ -10,24 +21,166 @@ function formatMd(content, options = {}) {
|
|
|
10
21
|
// Shift headers up or down by the specified number of levels if shiftHeaders is enabled and file is markdown
|
|
11
22
|
if (options.shiftHeaders) {
|
|
12
23
|
fileContents = fileContents.replace(/^(#{1,6})\s/gm, (match, hashes) => {
|
|
13
|
-
const currentLevel = hashes.length
|
|
14
|
-
const shiftAmount = Number(options.shiftHeaders)
|
|
15
|
-
const newLevel = Math.max(1, Math.min(6, currentLevel + shiftAmount))
|
|
16
|
-
return '#'.repeat(newLevel) + ' '
|
|
24
|
+
const currentLevel = hashes.length
|
|
25
|
+
const shiftAmount = Number(options.shiftHeaders)
|
|
26
|
+
const newLevel = Math.max(1, Math.min(6, currentLevel + shiftAmount))
|
|
27
|
+
return '#'.repeat(newLevel) + ' '
|
|
17
28
|
})
|
|
18
29
|
}
|
|
19
30
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
return fileContents
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function selectMarkdownSections(content, options = {}) {
|
|
35
|
+
const requestedSections = [
|
|
36
|
+
...coerceListOption(options.section),
|
|
37
|
+
...coerceListOption(options.sections)
|
|
38
|
+
]
|
|
39
|
+
const requestedHeadings = [
|
|
40
|
+
...coerceHeadingLevels(options.heading),
|
|
41
|
+
...coerceHeadingLevels(options.headings)
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
if (!requestedSections.length && !requestedHeadings.length) {
|
|
45
|
+
return content
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const headings = parseMarkdownHeadings(content)
|
|
49
|
+
const sectionNames = requestedSections.map(normalizeHeadingText)
|
|
50
|
+
const ranges = []
|
|
51
|
+
const missingSections = new Set(sectionNames)
|
|
52
|
+
|
|
53
|
+
headings.forEach((heading) => {
|
|
54
|
+
if (sectionNames.includes(heading.normalizedText)) {
|
|
55
|
+
ranges.push({ start: heading.start, end: heading.end })
|
|
56
|
+
missingSections.delete(heading.normalizedText)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (requestedHeadings.includes(heading.level)) {
|
|
60
|
+
ranges.push({ start: heading.start, end: heading.end })
|
|
25
61
|
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
if (missingSections.size && !options.allowMissingSections) {
|
|
65
|
+
const missing = Array.from(missingSections).join(', ')
|
|
66
|
+
throw new Error(`Missing markdown section${missingSections.size > 1 ? 's' : ''}: ${missing}`)
|
|
26
67
|
}
|
|
27
68
|
|
|
28
|
-
|
|
69
|
+
const mergedRanges = mergeRanges(ranges)
|
|
70
|
+
if (!mergedRanges.length) {
|
|
71
|
+
return ''
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return mergedRanges.map((range) => content.slice(range.start, range.end).trim()).join('\n\n')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function parseMarkdownHeadings(content) {
|
|
78
|
+
const headings = []
|
|
79
|
+
const lineRegex = /.*(?:\r\n|\n|\r|$)/g
|
|
80
|
+
let match
|
|
81
|
+
let offset = 0
|
|
82
|
+
let fenceMarker = null
|
|
83
|
+
|
|
84
|
+
while ((match = lineRegex.exec(content)) !== null) {
|
|
85
|
+
const line = match[0]
|
|
86
|
+
if (!line) break
|
|
87
|
+
|
|
88
|
+
const lineText = line.replace(/\r?\n$|\r$/, '')
|
|
89
|
+
const fenceMatch = lineText.match(/^ {0,3}(`{3,}|~{3,})/)
|
|
90
|
+
if (fenceMarker) {
|
|
91
|
+
if (fenceMatch && fenceMatch[1][0] === fenceMarker[0] && fenceMatch[1].length >= fenceMarker.length) {
|
|
92
|
+
fenceMarker = null
|
|
93
|
+
}
|
|
94
|
+
offset += line.length
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (fenceMatch) {
|
|
99
|
+
fenceMarker = fenceMatch[1]
|
|
100
|
+
offset += line.length
|
|
101
|
+
continue
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const headingMatch = lineText.match(/^ {0,3}(#{1,6})(?:[ \t]+|$)(.*)$/)
|
|
105
|
+
if (headingMatch) {
|
|
106
|
+
const text = cleanHeadingText(headingMatch[2])
|
|
107
|
+
headings.push({
|
|
108
|
+
level: headingMatch[1].length,
|
|
109
|
+
text,
|
|
110
|
+
normalizedText: normalizeHeadingText(text),
|
|
111
|
+
start: offset,
|
|
112
|
+
end: content.length
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
offset += line.length
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
headings.forEach((heading, index) => {
|
|
120
|
+
const nextHeading = headings.slice(index + 1).find((candidate) => candidate.level <= heading.level)
|
|
121
|
+
heading.end = nextHeading ? nextHeading.start : content.length
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
return headings
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function cleanHeadingText(text = '') {
|
|
128
|
+
return stripSimpleMarkdownLinks(text.replace(/[ \t]+#+[ \t]*$/, '').trim())
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function normalizeHeadingText(text = '') {
|
|
132
|
+
return cleanHeadingText(String(text))
|
|
133
|
+
.replace(/[`*_~]/g, '')
|
|
134
|
+
.replace(/\s+/g, ' ')
|
|
135
|
+
.trim()
|
|
136
|
+
.toLowerCase()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function stripSimpleMarkdownLinks(text = '') {
|
|
140
|
+
return text.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function coerceListOption(value) {
|
|
144
|
+
if (typeof value === 'undefined' || value === null || value === false) {
|
|
145
|
+
return []
|
|
146
|
+
}
|
|
147
|
+
if (Array.isArray(value)) {
|
|
148
|
+
return value.map((item) => String(item).trim()).filter(Boolean)
|
|
149
|
+
}
|
|
150
|
+
return String(value)
|
|
151
|
+
.replace(/^\[|\]$/g, '')
|
|
152
|
+
.split(',')
|
|
153
|
+
.map((item) => item.trim())
|
|
154
|
+
.filter(Boolean)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function coerceHeadingLevels(value) {
|
|
158
|
+
return coerceListOption(value)
|
|
159
|
+
.map((item) => Number(item))
|
|
160
|
+
.filter((item) => Number.isInteger(item) && item >= 1 && item <= 6)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function mergeRanges(ranges) {
|
|
164
|
+
return ranges
|
|
165
|
+
.filter((range) => range && Number.isInteger(range.start) && Number.isInteger(range.end) && range.end > range.start)
|
|
166
|
+
.sort((a, b) => a.start - b.start || b.end - a.end)
|
|
167
|
+
.reduce((merged, range) => {
|
|
168
|
+
const previous = merged[merged.length - 1]
|
|
169
|
+
if (previous && range.start <= previous.end) {
|
|
170
|
+
previous.end = Math.max(previous.end, range.end)
|
|
171
|
+
return merged
|
|
172
|
+
}
|
|
173
|
+
merged.push({ start: range.start, end: range.end })
|
|
174
|
+
return merged
|
|
175
|
+
}, [])
|
|
29
176
|
}
|
|
30
177
|
|
|
31
178
|
module.exports = {
|
|
32
|
-
formatMd
|
|
33
|
-
|
|
179
|
+
formatMd,
|
|
180
|
+
parseMarkdownHeadings,
|
|
181
|
+
selectMarkdownSections,
|
|
182
|
+
normalizeHeadingText,
|
|
183
|
+
coerceListOption,
|
|
184
|
+
coerceHeadingLevels,
|
|
185
|
+
mergeRanges
|
|
186
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
const { test } = require('uvu')
|
|
2
|
+
const assert = require('uvu/assert')
|
|
3
|
+
const {
|
|
4
|
+
formatMd,
|
|
5
|
+
parseMarkdownHeadings,
|
|
6
|
+
normalizeHeadingText
|
|
7
|
+
} = require('./format-md')
|
|
8
|
+
|
|
9
|
+
const SAMPLE = `---
|
|
10
|
+
title: Example
|
|
11
|
+
---
|
|
12
|
+
# Package Name
|
|
13
|
+
|
|
14
|
+
Intro text.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Install the package.
|
|
19
|
+
|
|
20
|
+
### Browser
|
|
21
|
+
|
|
22
|
+
Browser install notes.
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
Use the package.
|
|
27
|
+
|
|
28
|
+
### Node
|
|
29
|
+
|
|
30
|
+
Node usage notes.
|
|
31
|
+
|
|
32
|
+
## API ##
|
|
33
|
+
|
|
34
|
+
API docs.
|
|
35
|
+
|
|
36
|
+
\`\`\`md
|
|
37
|
+
## Ignored Code Heading
|
|
38
|
+
\`\`\`
|
|
39
|
+
|
|
40
|
+
## [Contributing](#contributing)
|
|
41
|
+
|
|
42
|
+
Contribution notes.
|
|
43
|
+
`
|
|
44
|
+
|
|
45
|
+
test('parseMarkdownHeadings finds ATX headings and ignores fenced code headings', () => {
|
|
46
|
+
const headings = parseMarkdownHeadings(SAMPLE)
|
|
47
|
+
assert.equal(
|
|
48
|
+
headings.map((heading) => heading.text),
|
|
49
|
+
['Package Name', 'Installation', 'Browser', 'Usage', 'Node', 'API', 'Contributing']
|
|
50
|
+
)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('normalizeHeadingText normalizes case, whitespace, closing hashes, and markdown links', () => {
|
|
54
|
+
assert.is(normalizeHeadingText(' Installation ## '), 'installation')
|
|
55
|
+
assert.is(normalizeHeadingText('[Contributing](#contributing)'), 'contributing')
|
|
56
|
+
assert.is(normalizeHeadingText('Quick Start'), 'quick start')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('formatMd sections selects named sections with nested child headings', () => {
|
|
60
|
+
const result = formatMd(SAMPLE, {
|
|
61
|
+
sections: 'Installation'
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
assert.ok(result.includes('## Installation'), 'includes requested section heading')
|
|
65
|
+
assert.ok(result.includes('### Browser'), 'includes nested child heading')
|
|
66
|
+
assert.not.ok(result.includes('## Usage'), 'excludes sibling section')
|
|
67
|
+
assert.not.ok(result.includes('Ignored Code Heading'), 'excludes unrelated fenced code heading')
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('formatMd sections accepts arrays and preserves source order', () => {
|
|
71
|
+
const result = formatMd(SAMPLE, {
|
|
72
|
+
sections: ['API', 'Installation']
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
assert.ok(result.indexOf('## Installation') < result.indexOf('## API'), 'uses source order')
|
|
76
|
+
assert.ok(result.includes('Install the package.'), 'includes first matched section')
|
|
77
|
+
assert.ok(result.includes('API docs.'), 'includes second matched section')
|
|
78
|
+
assert.not.ok(result.includes('## Usage'), 'excludes unselected middle section')
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test('formatMd section shorthand works', () => {
|
|
82
|
+
const result = formatMd(SAMPLE, {
|
|
83
|
+
section: 'Usage'
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
assert.ok(result.includes('## Usage'), 'includes shorthand section')
|
|
87
|
+
assert.ok(result.includes('### Node'), 'includes shorthand section children')
|
|
88
|
+
assert.not.ok(result.includes('## Installation'), 'excludes previous sibling')
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test('formatMd combines section and sections options', () => {
|
|
92
|
+
const result = formatMd(SAMPLE, {
|
|
93
|
+
section: 'Installation',
|
|
94
|
+
sections: 'API'
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
assert.ok(result.includes('## Installation'), 'includes section shorthand')
|
|
98
|
+
assert.ok(result.includes('## API'), 'includes sections option')
|
|
99
|
+
assert.not.ok(result.includes('## Usage'), 'excludes unselected section')
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('formatMd headings selects sections by heading level', () => {
|
|
103
|
+
const result = formatMd(SAMPLE, {
|
|
104
|
+
headings: [3]
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
assert.ok(result.includes('### Browser'), 'includes first h3 section')
|
|
108
|
+
assert.ok(result.includes('### Node'), 'includes second h3 section')
|
|
109
|
+
assert.not.ok(result.includes('## Installation'), 'excludes h2 parent')
|
|
110
|
+
assert.not.ok(result.includes('## API'), 'excludes h2 sibling')
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
test('formatMd headings accepts bracketed string values', () => {
|
|
114
|
+
const result = formatMd(SAMPLE, {
|
|
115
|
+
headings: '[3]'
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
assert.ok(result.includes('### Browser'), 'includes h3 from bracketed string')
|
|
119
|
+
assert.not.ok(result.includes('## Installation'), 'excludes h2 parent')
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
test('formatMd headings suppresses duplicate nested ranges', () => {
|
|
123
|
+
const result = formatMd(SAMPLE, {
|
|
124
|
+
headings: [2, 3]
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
assert.is(result.match(/### Browser/g).length, 1)
|
|
128
|
+
assert.is(result.match(/### Node/g).length, 1)
|
|
129
|
+
assert.ok(result.includes('## Installation'), 'includes h2 section')
|
|
130
|
+
assert.ok(result.includes('## Usage'), 'includes h2 sibling')
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
test('formatMd combines sections and headings as a deduped union', () => {
|
|
134
|
+
const result = formatMd(SAMPLE, {
|
|
135
|
+
sections: 'Usage',
|
|
136
|
+
headings: [3]
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
assert.ok(result.includes('### Browser'), 'includes h3 selected by level')
|
|
140
|
+
assert.ok(result.includes('## Usage'), 'includes named section')
|
|
141
|
+
assert.is(result.match(/### Node/g).length, 1)
|
|
142
|
+
assert.not.ok(result.includes('## API'), 'excludes unselected h2')
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('formatMd extracts before removeLeadingH1 and shiftHeaders', () => {
|
|
146
|
+
const result = formatMd(SAMPLE, {
|
|
147
|
+
sections: 'Installation',
|
|
148
|
+
removeLeadingH1: true,
|
|
149
|
+
shiftHeaders: 1
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
assert.ok(result.includes('### Installation'), 'shifts selected h2 after extraction')
|
|
153
|
+
assert.ok(result.includes('#### Browser'), 'shifts nested h3 after extraction')
|
|
154
|
+
assert.not.ok(result.includes('# Package Name'), 'does not include original leading h1')
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
test('formatMd throws when requested section is missing by default', () => {
|
|
158
|
+
assert.throws(() => {
|
|
159
|
+
formatMd(SAMPLE, {
|
|
160
|
+
sections: 'Missing'
|
|
161
|
+
})
|
|
162
|
+
}, /Missing markdown section: missing/)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
test('formatMd can ignore missing requested sections', () => {
|
|
166
|
+
const result = formatMd(SAMPLE, {
|
|
167
|
+
sections: 'Missing,Usage',
|
|
168
|
+
allowMissingSections: true
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
assert.ok(result.includes('## Usage'), 'includes found section')
|
|
172
|
+
assert.not.ok(result.includes('## Installation'), 'excludes unrequested section')
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
test.run()
|
package/types/src/cli-run.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getGlobGroupsFromArgs } from "@davidwells/dx-args";
|
|
1
|
+
import { getGlobGroupsFromArgs } from "@davidwells/dx-args/src/globparse";
|
|
2
2
|
export function parseCliArgv(rawArgv?: any[]): any;
|
|
3
3
|
export function normalizeCliOptions(parsed: any): any;
|
|
4
4
|
export function runCli(options: {}, rawArgv: any, deps?: {}): Promise<any>;
|
package/types/src/globparse.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { getGlobGroupsFromArgs } from "@davidwells/dx-args";
|
|
2
|
-
import { isArrayLike } from "@davidwells/dx-args";
|
|
3
|
-
import { stringLooksLikeFile } from "@davidwells/dx-args";
|
|
4
|
-
import { getValue } from "@davidwells/dx-args";
|
|
5
|
-
import { trimLeadingDashes } from "@davidwells/dx-args";
|
|
6
|
-
import { removeNodeModules } from "@davidwells/dx-args";
|
|
7
|
-
import { coerceStringToRegex } from "@davidwells/dx-args";
|
|
8
|
-
import { convertToArray } from "@davidwells/dx-args";
|
|
9
|
-
import { addValue } from "@davidwells/dx-args";
|
|
10
|
-
import { customIsGlob } from "@davidwells/dx-args";
|
|
1
|
+
import { getGlobGroupsFromArgs } from "@davidwells/dx-args/src/globparse";
|
|
2
|
+
import { isArrayLike } from "@davidwells/dx-args/src/globparse";
|
|
3
|
+
import { stringLooksLikeFile } from "@davidwells/dx-args/src/globparse";
|
|
4
|
+
import { getValue } from "@davidwells/dx-args/src/globparse";
|
|
5
|
+
import { trimLeadingDashes } from "@davidwells/dx-args/src/globparse";
|
|
6
|
+
import { removeNodeModules } from "@davidwells/dx-args/src/globparse";
|
|
7
|
+
import { coerceStringToRegex } from "@davidwells/dx-args/src/globparse";
|
|
8
|
+
import { convertToArray } from "@davidwells/dx-args/src/globparse";
|
|
9
|
+
import { addValue } from "@davidwells/dx-args/src/globparse";
|
|
10
|
+
import { customIsGlob } from "@davidwells/dx-args/src/globparse";
|
|
11
11
|
export { getGlobGroupsFromArgs, isArrayLike, stringLooksLikeFile, getValue, trimLeadingDashes, removeNodeModules, coerceStringToRegex, convertToArray, addValue, customIsGlob };
|
|
12
12
|
//# sourceMappingURL=globparse.d.ts.map
|
|
@@ -1,2 +1,14 @@
|
|
|
1
1
|
export function formatMd(content: any, options?: {}): any;
|
|
2
|
+
export function parseMarkdownHeadings(content: any): {
|
|
3
|
+
level: number;
|
|
4
|
+
text: string;
|
|
5
|
+
normalizedText: string;
|
|
6
|
+
start: number;
|
|
7
|
+
end: any;
|
|
8
|
+
}[];
|
|
9
|
+
export function selectMarkdownSections(content: any, options?: {}): any;
|
|
10
|
+
export function normalizeHeadingText(text?: string): string;
|
|
11
|
+
export function coerceListOption(value: any): string[];
|
|
12
|
+
export function coerceHeadingLevels(value: any): number[];
|
|
13
|
+
export function mergeRanges(ranges: any): any;
|
|
2
14
|
//# sourceMappingURL=format-md.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-md.d.ts","sourceRoot":"","sources":["../../../src/utils/format-md.js"],"names":[],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"file":"format-md.d.ts","sourceRoot":"","sources":["../../../src/utils/format-md.js"],"names":[],"mappings":"AAGA,0DA4BC;AAuCD;;;;;;IAgDC;AArFD,wEAmCC;AAwDD,4DAMC;AAMD,uDAQC;AAED,0DAIC;AAED,8CAaC"}
|
package/types/src/utils/fs.d.ts
CHANGED
|
@@ -30,6 +30,6 @@ export function getGitignoreContents(filePath?: string): Promise<string[]>;
|
|
|
30
30
|
* @returns {string} Relative path
|
|
31
31
|
*/
|
|
32
32
|
export function convertToRelativePath(file: string, cwd: string): string;
|
|
33
|
-
import fs_1 = require("fs");
|
|
33
|
+
import fs_1 = require("node:fs/promises");
|
|
34
34
|
import fs = fs_1.promises;
|
|
35
35
|
//# sourceMappingURL=fs.d.ts.map
|
package/types/_tests/config.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../_tests/config.js"],"names":[],"mappings":"AACA,iCAAoD;AACpD,0CAAyD;AACzD,gCAAmD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../_tests/errors.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"simple.d.ts","sourceRoot":"","sources":["../../../../_tests/fixtures/js/simple.js"],"names":[],"mappings":"AAqBA;;GAEG;AAIH;;mBAEmB;AAGnB,sBAAa"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=local-code-file-lines.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-code-file-lines.d.ts","sourceRoot":"","sources":["../../../_tests/fixtures/local-code-file-lines.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-code-file.d.ts","sourceRoot":"","sources":["../../../_tests/fixtures/local-code-file.js"],"names":[],"mappings":"AAYqB,4BAGpB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-code-id.d.ts","sourceRoot":"","sources":["../../../_tests/fixtures/local-code-id.js"],"names":[],"mappings":"AAUiB,qEAyBhB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transforms-toc.test.d.ts","sourceRoot":"","sources":["../../_tests/transforms-toc.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transforms.test.d.ts","sourceRoot":"","sources":["../../_tests/transforms.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../_tests/utils/diff.js"],"names":[],"mappings":"AA8HiB,2DAShB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"argparse.test.d.ts","sourceRoot":"","sources":["../../../src/argparse/argparse.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"splitOutsideQuotes.test.d.ts","sourceRoot":"","sources":["../../../src/argparse/splitOutsideQuotes.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-run.test.d.ts","sourceRoot":"","sources":["../../src/cli-run.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"globparse.test.d.ts","sourceRoot":"","sources":["../../src/globparse.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/index.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-github-file.test.d.ts","sourceRoot":"","sources":["../../../../src/transforms/code/resolve-github-file.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fs.test.d.ts","sourceRoot":"","sources":["../../../src/utils/fs.test.js"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"text.test.d.ts","sourceRoot":"","sources":["../../../src/utils/text.test.js"],"names":[],"mappings":""}
|