markdown-magic 3.0.0 → 3.0.1
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/README.md +43 -29
- package/lib/block-parser-js.test.js +148 -156
- package/lib/block-parser.js +255 -262
- package/lib/block-parser.test.js +43 -6
- package/lib/cli.js +30 -19
- package/lib/cli.test.js +73 -73
- package/lib/globals.d.ts +66 -0
- package/lib/index.js +43 -9
- package/lib/process-contents.js +80 -39
- package/lib/process-file.js +4 -1
- package/lib/transforms/code.js +4 -10
- package/lib/transforms/file.js +7 -10
- package/lib/transforms/index.js +0 -0
- package/lib/transforms/remote.js +2 -3
- package/lib/transforms/sectionToc.js +18 -0
- package/lib/transforms/toc.js +10 -335
- package/lib/types.js +11 -0
- package/lib/utils/fs.js +21 -19
- package/lib/utils/fs.test.js +4 -5
- package/lib/utils/logs.js +7 -2
- package/lib/utils/md/filters.js +5 -5
- package/lib/utils/md/find-code-blocks.js +16 -8
- package/lib/utils/md/find-frontmatter.js +11 -13
- package/lib/utils/md/find-frontmatter.test.js +2 -2
- package/lib/utils/md/find-html-tags.js +1 -1
- package/lib/utils/md/find-images-md.js +27 -0
- package/lib/utils/md/find-images.js +39 -34
- package/lib/utils/md/find-links.js +72 -54
- package/lib/utils/md/find-unmatched-html-tags.js +1 -2
- package/lib/utils/md/fixtures/file-with-links.md +10 -0
- package/lib/utils/md/md.test.js +72 -4
- package/lib/utils/md/parse.js +91 -67
- package/lib/utils/regex-timeout.js +2 -1
- package/lib/utils/regex.js +3 -2
- package/lib/utils/remoteRequest.js +1 -0
- package/lib/utils/syntax.js +3 -0
- package/lib/utils/text.js +71 -3
- package/lib/utils/text.test.js +3 -9
- package/lib/utils/toc.js +315 -0
- package/package.json +7 -3
- package/lib/options-parser.js +0 -498
- package/lib/options-parser.test.js +0 -1237
- package/lib/utils/html-to-json/compat.js +0 -42
- package/lib/utils/html-to-json/format.js +0 -64
- package/lib/utils/html-to-json/index.js +0 -37
- package/lib/utils/html-to-json/lexer.js +0 -345
- package/lib/utils/html-to-json/parser.js +0 -146
- package/lib/utils/html-to-json/stringify.js +0 -37
- package/lib/utils/html-to-json/tags.js +0 -171
|
@@ -49,6 +49,10 @@ authors:
|
|
|
49
49
|
|
|
50
50
|

|
|
51
51
|
|
|
52
|
+
This is the weird markdown link syntax <https://foooooooooooo.com>
|
|
53
|
+
|
|
54
|
+
this is less than sign
|
|
55
|
+
|
|
52
56
|
Hear Bob Bobster discuss the evolution of Serverless and the launch of ABC at the AWS Serverless Community Day.
|
|
53
57
|
|
|
54
58
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/KX7tj3giizI" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>
|
|
@@ -61,6 +65,12 @@ Hear Bob Bobster discuss the evolution of Serverless and the launch of ABC at th
|
|
|
61
65
|
<img src="/img/deploy/button.svg">
|
|
62
66
|
</a>
|
|
63
67
|
|
|
68
|
+
|
|
69
|
+
<a href="https://www.yoursite.com/pricing?utm_source=active%20users&utm_medium=email&utm_campaign=feature%20launch&utm_content=bottom%20cta%20button">
|
|
70
|
+
Utm params link
|
|
71
|
+
</a>
|
|
72
|
+
|
|
73
|
+
|
|
64
74
|
Title xyz
|
|
65
75
|
============================
|
|
66
76
|
|
package/lib/utils/md/md.test.js
CHANGED
|
@@ -3,10 +3,9 @@ const path = require('path')
|
|
|
3
3
|
const { test } = require('uvu')
|
|
4
4
|
const assert = require('uvu/assert')
|
|
5
5
|
const { deepLog } = require('../logs')
|
|
6
|
-
const { stringify } = require('../html-to-json')
|
|
7
6
|
const { parseMarkdown } = require('./parse')
|
|
8
7
|
const { findLinks } = require('./find-links')
|
|
9
|
-
const {
|
|
8
|
+
const { parseFrontmatter } = require('./find-frontmatter')
|
|
10
9
|
|
|
11
10
|
const FILE_PATH = path.join(__dirname, 'fixtures/file-with-links.md')
|
|
12
11
|
// const FILE_PATH = path.join(__dirname, 'fixtures/2022-01-22-date-in-filename.md')
|
|
@@ -14,7 +13,6 @@ const fileContents = fs.readFileSync(FILE_PATH, 'utf-8')
|
|
|
14
13
|
|
|
15
14
|
test('parseMarkdown API', async () => {
|
|
16
15
|
const res = parseMarkdown(fileContents, { filePath: FILE_PATH })
|
|
17
|
-
// deepLog(res)
|
|
18
16
|
assert.is(typeof res, 'object')
|
|
19
17
|
assert.is(typeof res.ast, 'object')
|
|
20
18
|
assert.is(typeof res.data, 'object')
|
|
@@ -23,8 +21,78 @@ test('parseMarkdown API', async () => {
|
|
|
23
21
|
assert.is(Array.isArray(res.errors), true)
|
|
24
22
|
})
|
|
25
23
|
|
|
24
|
+
test('Verify contents', async () => {
|
|
25
|
+
const res = parseMarkdown(fileContents, {
|
|
26
|
+
filePath: FILE_PATH
|
|
27
|
+
})
|
|
28
|
+
deepLog('Results:', res)
|
|
29
|
+
assert.equal(res.links, [
|
|
30
|
+
'https://funky-frontmatter.com',
|
|
31
|
+
'https://www.front.com/blog/open-beta-changes',
|
|
32
|
+
'https://youtu.be/A1bL4pHuivU',
|
|
33
|
+
'https://foooooooooooo.com',
|
|
34
|
+
'https://www.youtube.com/embed/KX7tj3giizI',
|
|
35
|
+
'https://app.netlify.com/start/deploy',
|
|
36
|
+
'https://www.yoursite.com/pricing?utm_source=active%20users&utm_medium=email&utm_campaign=feature%20launch&utm_content=bottom%20cta%20button',
|
|
37
|
+
'https://ABC.com/sign-up',
|
|
38
|
+
'http://jobs.ABC.net',
|
|
39
|
+
'/foobar'
|
|
40
|
+
])
|
|
41
|
+
assert.equal(res.images, [
|
|
42
|
+
'/assets/images/lol-frontmatter.jpg',
|
|
43
|
+
'/assets/images/lol.jpg',
|
|
44
|
+
'assets/images/san-juan-mountains.jpg',
|
|
45
|
+
'https://res.cloudinary.com/ABC/image/upload/f_auto,q_auto/c_fill,w_1200/v1668114635/what-you-can-build_p8uape.png',
|
|
46
|
+
'https://avatars2.githubusercontent.com/u/532272?v=3&s=400',
|
|
47
|
+
'https://dope-frontmatter.com/img/deploy/button.svg',
|
|
48
|
+
'https://frontmatter.com/img/deploy/button.svg',
|
|
49
|
+
'/img/in-nested-frontmatter/button.svg',
|
|
50
|
+
'https://www.netlify.com/img/deploy/button.svg',
|
|
51
|
+
'https://fooo.com/img/deploy/button.svg',
|
|
52
|
+
'/img/deploy/button.svg',
|
|
53
|
+
'img/deploy/button.svg',
|
|
54
|
+
'../img/deploy/button.svg'
|
|
55
|
+
])
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test('opts - includeAst false', async () => {
|
|
59
|
+
const res = parseMarkdown(fileContents, {
|
|
60
|
+
filePath: FILE_PATH,
|
|
61
|
+
})
|
|
62
|
+
// deepLog('Results:', res)
|
|
63
|
+
assert.ok(Array.isArray(res.ast))
|
|
64
|
+
/* Disable AST */
|
|
65
|
+
const resTwo = parseMarkdown(fileContents, {
|
|
66
|
+
filePath: FILE_PATH,
|
|
67
|
+
includeAst: false,
|
|
68
|
+
})
|
|
69
|
+
// deepLog('Results two:', resTwo)
|
|
70
|
+
assert.ok(typeof resTwo.ast === 'undefined')
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('opts - includeImages false', async () => {
|
|
74
|
+
const res = parseMarkdown(fileContents, {
|
|
75
|
+
filePath: FILE_PATH,
|
|
76
|
+
// includeAst: false,
|
|
77
|
+
includeImages: false,
|
|
78
|
+
})
|
|
79
|
+
deepLog('Results:', res)
|
|
80
|
+
assert.ok(typeof res.links === 'object')
|
|
81
|
+
assert.ok(typeof res.images === 'undefined')
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test('opts - includeLinks false', async () => {
|
|
85
|
+
const res = parseMarkdown(fileContents, {
|
|
86
|
+
filePath: FILE_PATH,
|
|
87
|
+
includeLinks: false,
|
|
88
|
+
})
|
|
89
|
+
deepLog('Results:', res)
|
|
90
|
+
assert.ok(typeof res.links === 'undefined')
|
|
91
|
+
assert.ok(typeof res.images === 'object')
|
|
92
|
+
})
|
|
93
|
+
|
|
26
94
|
// test('File have correct extensions', async () => {
|
|
27
|
-
// const { data } =
|
|
95
|
+
// const { data } = parseFrontmatter(fileWithLinks, FILE_PATH)
|
|
28
96
|
// console.log('frontmatter data', data)
|
|
29
97
|
// const links = findLinks(fileWithLinks, { frontmatter: data })
|
|
30
98
|
// // console.log('links', links)
|
package/lib/utils/md/parse.js
CHANGED
|
@@ -1,54 +1,74 @@
|
|
|
1
|
-
|
|
2
|
-
const {
|
|
3
|
-
const { parse } = require('../html-to-json')
|
|
4
|
-
const { getLineCount } = require('./utils')
|
|
1
|
+
const { parse } = require('micro-mdx-parser')
|
|
2
|
+
const { parseFrontmatter } = require('./find-frontmatter')
|
|
5
3
|
const { findUnmatchedHtmlTags } = require('./find-unmatched-html-tags')
|
|
6
4
|
const { findLinks } = require('./find-links')
|
|
7
5
|
const { findDate } = require('./find-date')
|
|
8
6
|
const { findCodeBlocks, REMOVE_CODE_BLOCK_REGEX } = require('./find-code-blocks')
|
|
9
|
-
|
|
10
|
-
// const { findHtmlTags } = require('./find-html-tags')
|
|
7
|
+
const { getLineCount } = require('./utils')
|
|
11
8
|
|
|
12
9
|
function parseMarkdown(text, opts = {}) {
|
|
13
|
-
const {
|
|
10
|
+
const {
|
|
11
|
+
filePath,
|
|
12
|
+
validator,
|
|
13
|
+
astParser,
|
|
14
|
+
includeAst = true,
|
|
15
|
+
includeLinks = true,
|
|
16
|
+
includeImages = true,
|
|
17
|
+
includeCodeBlocks = true,
|
|
18
|
+
includePositions = false,
|
|
19
|
+
includeRawFrontmatter = false,
|
|
20
|
+
} = opts
|
|
14
21
|
let errors = []
|
|
15
|
-
let
|
|
22
|
+
let result = {}
|
|
16
23
|
let alreadySetError = false
|
|
17
24
|
try {
|
|
18
|
-
|
|
25
|
+
result = parseFrontmatter(text)
|
|
19
26
|
} catch (err) {
|
|
20
27
|
console.log(`Broken frontmatter in ${filePath}...`)
|
|
21
28
|
errors.push(err.message)
|
|
22
29
|
alreadySetError = true
|
|
23
30
|
}
|
|
24
|
-
const { data, content = '',
|
|
31
|
+
const { data, content = '', frontMatterRaw = '' } = result
|
|
25
32
|
if (!data || !Object.keys(data).length) {
|
|
26
33
|
if (!alreadySetError) {
|
|
27
34
|
errors.push(`Missing or broken frontmatter in ${filePath}. Double check file for --- frontmatter tags`)
|
|
28
35
|
}
|
|
29
36
|
}
|
|
30
37
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
let links
|
|
39
|
+
let images
|
|
40
|
+
if (includeLinks || includeImages) {
|
|
41
|
+
const linkData = findLinks(text, {
|
|
42
|
+
frontmatter: data
|
|
43
|
+
})
|
|
44
|
+
links = linkData.links
|
|
45
|
+
images = linkData.images
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let ast = []
|
|
49
|
+
if (includeAst) {
|
|
50
|
+
/* If custom parser supplied */
|
|
51
|
+
if (astParser) {
|
|
52
|
+
ast = astParser(content, opts)
|
|
53
|
+
} else {
|
|
54
|
+
/* Default parser */
|
|
55
|
+
ast = parse(content, {
|
|
56
|
+
includePositions,
|
|
57
|
+
// offset: {
|
|
58
|
+
// lineOffset: getLineCount(frontMatterRaw),
|
|
59
|
+
// charOffset: frontMatterRaw.length
|
|
60
|
+
// }
|
|
61
|
+
})
|
|
48
62
|
}
|
|
49
|
-
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// console.log('html', html)
|
|
50
66
|
// console.log(`htmlTags ${filePath}`, htmlTags)
|
|
51
|
-
|
|
67
|
+
let codeBlocks
|
|
68
|
+
if (includeCodeBlocks) {
|
|
69
|
+
codeBlocks = findCodeBlocks(text, { filePath, includePositions })
|
|
70
|
+
}
|
|
71
|
+
|
|
52
72
|
// console.log(`codeBlocks ${filePath}`, codeBlocks)
|
|
53
73
|
const tagsErrors = findUnmatchedHtmlTags(text, filePath)
|
|
54
74
|
|
|
@@ -58,9 +78,9 @@ function parseMarkdown(text, opts = {}) {
|
|
|
58
78
|
// }
|
|
59
79
|
|
|
60
80
|
let htmlValidation = []
|
|
61
|
-
if (
|
|
62
|
-
const contentsNoCodeBlocks = content.replace(REMOVE_CODE_BLOCK_REGEX, '')
|
|
63
|
-
htmlValidation =
|
|
81
|
+
if (typeof validator === 'function') {
|
|
82
|
+
// const contentsNoCodeBlocks = content.replace(REMOVE_CODE_BLOCK_REGEX, '')
|
|
83
|
+
htmlValidation = validator(content, filePath)
|
|
64
84
|
}
|
|
65
85
|
|
|
66
86
|
if (htmlValidation && htmlValidation.length) {
|
|
@@ -76,45 +96,49 @@ function parseMarkdown(text, opts = {}) {
|
|
|
76
96
|
errors = errors.concat(codeBlocks.errors)
|
|
77
97
|
}
|
|
78
98
|
|
|
79
|
-
const
|
|
99
|
+
const frontmatter = data || {}
|
|
80
100
|
const date = findDate({
|
|
81
|
-
frontmatter
|
|
101
|
+
frontmatter,
|
|
82
102
|
filePath
|
|
83
103
|
})
|
|
84
104
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/*
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
105
|
+
const parseResult = {}
|
|
106
|
+
|
|
107
|
+
if (filePath) {
|
|
108
|
+
parseResult.filePath = filePath
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (date) {
|
|
112
|
+
parseResult.date = date
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (includeAst) {
|
|
116
|
+
parseResult.ast = ast
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Include frontmatter as data object */
|
|
120
|
+
parseResult.data = frontmatter
|
|
121
|
+
|
|
122
|
+
if (includeRawFrontmatter) {
|
|
123
|
+
parseResult.frontMatterRaw = frontMatterRaw
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (includeLinks) {
|
|
127
|
+
parseResult.links = links
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (includeImages) {
|
|
131
|
+
parseResult.images = images
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (includeCodeBlocks) {
|
|
135
|
+
parseResult.codeBlocks = codeBlocks.blocks
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
parseResult.content = content
|
|
139
|
+
parseResult.errors = errors
|
|
140
|
+
|
|
141
|
+
return parseResult
|
|
118
142
|
}
|
|
119
143
|
|
|
120
144
|
module.exports = {
|
|
@@ -33,7 +33,8 @@ This is normal text in markdown. Keep it.
|
|
|
33
33
|
// var pattern = /([ \t]*)(?:<!-{2,}(?:.*|\r?|\n?|\s*)docs-start\s*([(\[\{]*[A-Za-z0-9_$-]*[)\]\}]*)\s*)((?:.*?|.*?\r?\n?)*?)<!-{2,}(?:.*|\r?|\n?|\s*)docs-end(?:.|\r?\n)*?-{2,}>/gim
|
|
34
34
|
|
|
35
35
|
function safeRegex(str) {
|
|
36
|
-
const
|
|
36
|
+
const syntax = 'md'
|
|
37
|
+
const syntaxInfo = getSyntaxInfo(syntax)
|
|
37
38
|
if (!syntaxInfo.pattern) {
|
|
38
39
|
throw new Error(`Unknown syntax "${syntax}"`)
|
|
39
40
|
}
|
package/lib/utils/regex.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// REGEX to look for regex
|
|
3
3
|
// https://github.com/kgryte/regex-regex/blob/master/lib/index.js
|
|
4
4
|
const REGEX_REGEX = /^\/((?:\\\/|[^\/])+)\/([imgy]*)$/
|
|
5
|
+
const LINEBREAK_MATCHER = /\r\n|[\r\n\u2028\u2029]/;
|
|
5
6
|
|
|
6
7
|
function escapeRegexString(string) {
|
|
7
8
|
if (typeof string !== 'string') {
|
|
@@ -54,7 +55,7 @@ function cleanStepMatches(matches) {
|
|
|
54
55
|
/**
|
|
55
56
|
* Match comment steps in files
|
|
56
57
|
*/
|
|
57
|
-
function getSteps() {
|
|
58
|
+
function getSteps(matches) {
|
|
58
59
|
const steps = cleanStepMatches(matches)
|
|
59
60
|
|
|
60
61
|
const sortedSteps = steps.reduce((accumulator, currentValue, currentIndex, array) => {
|
|
@@ -97,7 +98,7 @@ const TABEL_ROW_REGEX = /^\s*\|.*?\|\s*$/
|
|
|
97
98
|
* @param {string} text The text to validate.
|
|
98
99
|
* @returns {boolean}
|
|
99
100
|
*/
|
|
100
|
-
const isTableRow = (text) => text.match(TABEL_ROW_REGEX)
|
|
101
|
+
const isTableRow = (text) => Boolean(text.match(TABEL_ROW_REGEX))
|
|
101
102
|
|
|
102
103
|
module.exports = {
|
|
103
104
|
REGEX_REGEX,
|
package/lib/utils/syntax.js
CHANGED
|
@@ -69,6 +69,9 @@ const syntaxMap = {
|
|
|
69
69
|
yml: yaml
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// Additional comment syntaxes for future
|
|
73
|
+
// https://github.com/apidoc/apidoc/tree/27566b48a9e8bad2fb3920c02473940917eabe70#supported-programming-languages
|
|
74
|
+
|
|
72
75
|
function getSyntaxInfo(syntax = '') {
|
|
73
76
|
return syntaxMap[syntax.toLowerCase()] || {}
|
|
74
77
|
}
|
package/lib/utils/text.js
CHANGED
|
@@ -37,6 +37,25 @@ function getTextBetweenChars(text, start, end) {
|
|
|
37
37
|
return text.slice(start, end)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Get text between two words
|
|
42
|
+
* @param {string} s
|
|
43
|
+
* @param {string} prefix
|
|
44
|
+
* @param {string} suffix
|
|
45
|
+
* @returns {string}
|
|
46
|
+
*/
|
|
47
|
+
function getTextBetweenWords(s, prefix, suffix) {
|
|
48
|
+
let i = s.indexOf(prefix)
|
|
49
|
+
if (i === -1) return ''
|
|
50
|
+
s = s.substring(i + prefix.length)
|
|
51
|
+
if (suffix) {
|
|
52
|
+
i = s.indexOf(suffix)
|
|
53
|
+
if (i === -1) return ''
|
|
54
|
+
s = s.substring(0, i)
|
|
55
|
+
}
|
|
56
|
+
return s
|
|
57
|
+
}
|
|
58
|
+
|
|
40
59
|
function replaceTextBetweenChars(str = '', start, end, newStr) {
|
|
41
60
|
return str.substring(0, start) + newStr + str.substring(end)
|
|
42
61
|
}
|
|
@@ -77,7 +96,7 @@ function stripIndent(string, indentation) {
|
|
|
77
96
|
|
|
78
97
|
/**
|
|
79
98
|
* Trim leading & trailing spaces/line breaks in code and keeps the indentation of the first non-empty line
|
|
80
|
-
* @param {string} str
|
|
99
|
+
* @param {string|number} str
|
|
81
100
|
* @returns string
|
|
82
101
|
*/
|
|
83
102
|
function trimString(str = '') {
|
|
@@ -149,10 +168,10 @@ function stripCommentBlockOld(str, syntax = 'md') {
|
|
|
149
168
|
/**
|
|
150
169
|
* Strip out comment blocks
|
|
151
170
|
* @param {string} str
|
|
152
|
-
* @param {'
|
|
171
|
+
* @param {typeof import('../types')['syntaxType']} syntax
|
|
153
172
|
* @returns {string} clean commentless string
|
|
154
173
|
*/
|
|
155
|
-
function stripComments(str,
|
|
174
|
+
function stripComments(str, syntax = 'md') {
|
|
156
175
|
const syntaxData = syntaxMap[syntax]
|
|
157
176
|
const [ openPattern, closePattern ] = syntaxData.pattern
|
|
158
177
|
const OR = (syntaxData.singleLine) ? `|\\s?[ \\t]*${syntaxData.singleLine}` : ''
|
|
@@ -236,7 +255,55 @@ function convertCommentSyntax(str, { from, to }) {
|
|
|
236
255
|
return str.replace(regexToUse, newText)
|
|
237
256
|
}
|
|
238
257
|
|
|
258
|
+
/**
|
|
259
|
+
* capitalize first letter
|
|
260
|
+
* @param {string} str
|
|
261
|
+
* @returns
|
|
262
|
+
*/
|
|
263
|
+
function capitalizeFirstLetter(str) {
|
|
264
|
+
return capitalize(str.charAt(0)) + str.slice(1)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* capitalize string
|
|
269
|
+
* @param {string} str
|
|
270
|
+
* @returns
|
|
271
|
+
*/
|
|
272
|
+
function capitalize(str = '') {
|
|
273
|
+
return str.toUpperCase()
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function camelCase(str = '') {
|
|
277
|
+
return str.replace(/[-_ ](\w)/g, (_, c) => c.toUpperCase())
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function kebabCase(str = '') {
|
|
281
|
+
return str.replace(/\B([A-Z])/g, '-$1').toLowerCase()
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|vs?\.?|via)$/i;
|
|
285
|
+
|
|
286
|
+
function toTitleCase(str = '') {
|
|
287
|
+
return str.replace(/[A-Za-z0-9\u00C0-\u00FF]+[^\s-]*/g, (match, index, title) => {
|
|
288
|
+
if (index > 0
|
|
289
|
+
&& index + match.length !== title.length
|
|
290
|
+
&& match.search(smallWords) > -1
|
|
291
|
+
&& title.charAt(index - 2) !== ':'
|
|
292
|
+
&& (title.charAt(index + match.length) !== '-' || title.charAt(index - 1) === '-')
|
|
293
|
+
&& title.charAt(index - 1).search(/[^\s-]/) < 0) {
|
|
294
|
+
return match.toLowerCase();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (match.substr(1).search(/[A-Z]|\../) > -1) {
|
|
298
|
+
return match;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return match.charAt(0).toUpperCase() + match.substr(1);
|
|
302
|
+
})
|
|
303
|
+
}
|
|
304
|
+
|
|
239
305
|
module.exports = {
|
|
306
|
+
toTitleCase,
|
|
240
307
|
getLines,
|
|
241
308
|
getLineCount,
|
|
242
309
|
getWordCount,
|
|
@@ -245,6 +312,7 @@ module.exports = {
|
|
|
245
312
|
getLastCharacter,
|
|
246
313
|
getRowAndColumnFromCharPos,
|
|
247
314
|
getTextBetweenChars,
|
|
315
|
+
getTextBetweenWords,
|
|
248
316
|
getTextBetweenLines,
|
|
249
317
|
replaceTextBetweenChars,
|
|
250
318
|
stripIndent,
|
package/lib/utils/text.test.js
CHANGED
|
@@ -88,9 +88,7 @@ nice
|
|
|
88
88
|
`
|
|
89
89
|
|
|
90
90
|
test('Remove Markdown comments', () => {
|
|
91
|
-
const parsedValue = stripComments(md,
|
|
92
|
-
syntax: 'md'
|
|
93
|
-
})
|
|
91
|
+
const parsedValue = stripComments(md, 'md')
|
|
94
92
|
/*
|
|
95
93
|
console.log('parsedValue')
|
|
96
94
|
logOutput(parsedValue)
|
|
@@ -162,9 +160,7 @@ console.log('inline') /* inline klsjlkajdsalkjd *****/
|
|
|
162
160
|
|
|
163
161
|
/* inline */
|
|
164
162
|
console.log('nice')
|
|
165
|
-
`,
|
|
166
|
-
syntax: 'js'
|
|
167
|
-
})
|
|
163
|
+
`, 'js')
|
|
168
164
|
/*
|
|
169
165
|
console.log('parsedValue')
|
|
170
166
|
logOutput(parsedValue)
|
|
@@ -195,9 +191,7 @@ test('Remove YAML comments', () => {
|
|
|
195
191
|
steve: 'cool' # inline comment
|
|
196
192
|
foo:
|
|
197
193
|
bar: lol
|
|
198
|
-
`,
|
|
199
|
-
syntax: 'yml'
|
|
200
|
-
})
|
|
194
|
+
`, 'yml')
|
|
201
195
|
|
|
202
196
|
/*
|
|
203
197
|
console.log('yml', dedentString(parsedValue))
|