md-processor 1.0.0
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/.github/workflows/test.yaml +21 -0
- package/LICENSE.md +21 -0
- package/README.md +28 -0
- package/bin/md-processor.js +17 -0
- package/index.js +9 -0
- package/lib/Block.js +17 -0
- package/lib/Markdown.js +55 -0
- package/lib/Processor.js +40 -0
- package/package.json +32 -0
- package/test/Block.test.js +60 -0
- package/test/Markdown.test.js +133 -0
- package/test/Processor.test.js +39 -0
- package/test/support/examples.js +64 -0
- package/test/support/multiBlock.md +6 -0
- package/test/support/multiImports.md +8 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
on:
|
|
3
|
+
- pull_request
|
|
4
|
+
- push
|
|
5
|
+
jobs:
|
|
6
|
+
test:
|
|
7
|
+
runs-on: ubuntu-20.04
|
|
8
|
+
strategy:
|
|
9
|
+
matrix:
|
|
10
|
+
node:
|
|
11
|
+
- '16'
|
|
12
|
+
- '18'
|
|
13
|
+
- '20'
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v3
|
|
16
|
+
- uses: actions/setup-node@v3
|
|
17
|
+
with:
|
|
18
|
+
node-version: ${{ matrix.node }}
|
|
19
|
+
- run: npm install
|
|
20
|
+
- run: npm test
|
|
21
|
+
- uses: codecov/codecov-action@v3
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Thomas Bergwinkl
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# md-processor
|
|
2
|
+
|
|
3
|
+
[](https://github.com/bergos/md-processor/actions/workflows/test.yaml)
|
|
4
|
+
[](https://www.npmjs.com/package/md-processor)
|
|
5
|
+
|
|
6
|
+
A preprocessor for markdown files.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
You can run `md-processor` with `npx` like shown below:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
nxp md-processor input.md > output.md
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
### Imports
|
|
19
|
+
|
|
20
|
+
Sections of other markdown files can be imported like this:
|
|
21
|
+
|
|
22
|
+
```markdown
|
|
23
|
+
@[import{section}](filename)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- `section`: The full header of the section to import
|
|
27
|
+
- `filename`: The path to the markdown file to import.
|
|
28
|
+
The path is relative to the input file.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander'
|
|
4
|
+
import Processor from '../lib/Processor.js'
|
|
5
|
+
|
|
6
|
+
const program = new Command()
|
|
7
|
+
|
|
8
|
+
program
|
|
9
|
+
.argument('<input>', 'markdown to process')
|
|
10
|
+
.action(async input => {
|
|
11
|
+
const processor = new Processor()
|
|
12
|
+
const result = await processor.process(input)
|
|
13
|
+
|
|
14
|
+
process.stdout.write(result)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
program.parse(process.argv)
|
package/index.js
ADDED
package/lib/Block.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class Block {
|
|
2
|
+
constructor ({ header = null, level = 0 } = {}) {
|
|
3
|
+
this.header = header
|
|
4
|
+
this.level = level
|
|
5
|
+
this.lines = []
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
append (line) {
|
|
9
|
+
this.lines.push(line)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
toString () {
|
|
13
|
+
return this.lines.join('\n')
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default Block
|
package/lib/Markdown.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises'
|
|
2
|
+
import Block from './Block.js'
|
|
3
|
+
|
|
4
|
+
const parseHeaderRegex = /(#+) (.*)/
|
|
5
|
+
|
|
6
|
+
class Markdown {
|
|
7
|
+
constructor () {
|
|
8
|
+
this.blocks = []
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get isEmpty () {
|
|
12
|
+
return this.blocks.length === 0
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get last () {
|
|
16
|
+
return this.blocks[this.blocks.length - 1]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
append ({ header, level } = {}) {
|
|
20
|
+
this.blocks.push(new Block({ header, level }))
|
|
21
|
+
|
|
22
|
+
return this
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
get (header) {
|
|
26
|
+
return this.blocks.find(block => block.header === header)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
parse (content) {
|
|
30
|
+
const lines = content.split('\n')
|
|
31
|
+
|
|
32
|
+
for (const line of lines) {
|
|
33
|
+
const parsed = line.match(parseHeaderRegex)
|
|
34
|
+
|
|
35
|
+
if (parsed) {
|
|
36
|
+
this.append({
|
|
37
|
+
header: parsed[2],
|
|
38
|
+
level: parsed[1]
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.last.append(line)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return this
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static async load (path) {
|
|
49
|
+
const content = (await readFile(path)).toString()
|
|
50
|
+
|
|
51
|
+
return new Markdown().parse(content)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default Markdown
|
package/lib/Processor.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises'
|
|
2
|
+
import { dirname, resolve } from 'node:path'
|
|
3
|
+
import Markdown from './Markdown.js'
|
|
4
|
+
|
|
5
|
+
const parseImportRegex = /@\[import{([^}]*)}]\(([^)]*)\)/g
|
|
6
|
+
|
|
7
|
+
class Processor {
|
|
8
|
+
constructor ({ path } = {}) {
|
|
9
|
+
this.path = path || process.cwd()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async process (path) {
|
|
13
|
+
path = resolve(this.path, path)
|
|
14
|
+
|
|
15
|
+
let content = (await readFile(path)).toString()
|
|
16
|
+
|
|
17
|
+
content = await this.processImports({ content, path })
|
|
18
|
+
|
|
19
|
+
return content
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async processImports ({ content, path }) {
|
|
23
|
+
const imports = new Map()
|
|
24
|
+
|
|
25
|
+
for (const [text, header, importPath] of [...content.matchAll(parseImportRegex)]) {
|
|
26
|
+
imports.set(text, { header, importPath })
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
for (const [text, { header, importPath }] of imports) {
|
|
30
|
+
const resolved = resolve(dirname(path), importPath)
|
|
31
|
+
const markdown = await Markdown.load(resolved)
|
|
32
|
+
|
|
33
|
+
content = content.replaceAll(text, markdown.get(header))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return content
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default Processor
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "md-processor",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A preprocessor for markdown files",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"md-processor": "bin/md-processor.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "stricter-standard && c8 --reporter=lcov --reporter=text-summary mocha"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/bergos/md-processor.git"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [],
|
|
18
|
+
"author": "Thomas Bergwinkl <bergi@axolotlfarm.org> (https://www.bergnet.org/people/bergi/card#me)",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/bergos/md-processor/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/bergos/md-processor",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"commander": "^10.0.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"c8": "^7.14.0",
|
|
29
|
+
"mocha": "^10.2.0",
|
|
30
|
+
"stricter-standard": "^0.2.0"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { strictEqual } from 'node:assert'
|
|
2
|
+
import { describe, it } from 'mocha'
|
|
3
|
+
import Block from '../lib/Block.js'
|
|
4
|
+
|
|
5
|
+
describe('Block', () => {
|
|
6
|
+
it('should be a constructor', () => {
|
|
7
|
+
strictEqual(typeof Block, 'function')
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('should assign the given header argument', () => {
|
|
11
|
+
const header = {}
|
|
12
|
+
const block = new Block({ header })
|
|
13
|
+
|
|
14
|
+
strictEqual(block.header, header)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('should assign the given level argument', () => {
|
|
18
|
+
const level = {}
|
|
19
|
+
const block = new Block({ level })
|
|
20
|
+
|
|
21
|
+
strictEqual(block.level, level)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('should have an empty array property named lines', () => {
|
|
25
|
+
const block = new Block()
|
|
26
|
+
|
|
27
|
+
strictEqual(Array.isArray(block.lines), true)
|
|
28
|
+
strictEqual(block.lines.length, 0)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
describe('.append', () => {
|
|
32
|
+
it('should be a method', () => {
|
|
33
|
+
const block = new Block()
|
|
34
|
+
|
|
35
|
+
strictEqual(typeof block.append, 'function')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('should append the given line', () => {
|
|
39
|
+
const line = 'test'
|
|
40
|
+
const block = new Block()
|
|
41
|
+
|
|
42
|
+
block.append(line)
|
|
43
|
+
|
|
44
|
+
strictEqual(block.lines.length, 1)
|
|
45
|
+
strictEqual(block.lines[0], line)
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe('.toString', () => {
|
|
50
|
+
it('should return all lines joined by a line break', () => {
|
|
51
|
+
const lines = ['abc', 'def']
|
|
52
|
+
const block = new Block()
|
|
53
|
+
|
|
54
|
+
block.append(lines[0])
|
|
55
|
+
block.append(lines[1])
|
|
56
|
+
|
|
57
|
+
strictEqual(block.toString(), lines.join('\n'))
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
})
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { deepStrictEqual, strictEqual } from 'node:assert'
|
|
2
|
+
import { describe, it } from 'mocha'
|
|
3
|
+
import Markdown from '../lib/Markdown.js'
|
|
4
|
+
import * as examples from './support/examples.js'
|
|
5
|
+
|
|
6
|
+
describe('Markdown', () => {
|
|
7
|
+
it('should be a constructor', () => {
|
|
8
|
+
strictEqual(typeof Markdown, 'function')
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('should have an empty array property named blocks', () => {
|
|
12
|
+
const markdown = new Markdown()
|
|
13
|
+
|
|
14
|
+
strictEqual(Array.isArray(markdown.blocks), true)
|
|
15
|
+
strictEqual(markdown.blocks.length, 0)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
describe('.isEmpty', () => {
|
|
19
|
+
it('should be a boolean property', () => {
|
|
20
|
+
const markdown = new Markdown()
|
|
21
|
+
|
|
22
|
+
strictEqual(typeof markdown.isEmpty, 'boolean')
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
describe('.last', () => {
|
|
27
|
+
it('should be a property pointing to the last block', () => {
|
|
28
|
+
const markdown = new Markdown().append({}).append({})
|
|
29
|
+
|
|
30
|
+
strictEqual(markdown.last, markdown.blocks[1])
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should be undefined if the object is empty', () => {
|
|
34
|
+
const markdown = new Markdown()
|
|
35
|
+
|
|
36
|
+
strictEqual(typeof markdown.last, 'undefined')
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
describe('.append', () => {
|
|
41
|
+
it('should be a method', () => {
|
|
42
|
+
const markdown = new Markdown()
|
|
43
|
+
|
|
44
|
+
strictEqual(typeof markdown.append, 'function')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('should append a new block with the given header and level', () => {
|
|
48
|
+
const header = 'test'
|
|
49
|
+
const level = '###'
|
|
50
|
+
const markdown = new Markdown()
|
|
51
|
+
|
|
52
|
+
markdown.append({ header, level })
|
|
53
|
+
|
|
54
|
+
strictEqual(markdown.blocks.length, 1)
|
|
55
|
+
strictEqual(markdown.blocks[0].header, header)
|
|
56
|
+
strictEqual(markdown.blocks[0].level, level)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should return this', () => {
|
|
60
|
+
const markdown = new Markdown()
|
|
61
|
+
|
|
62
|
+
const result = markdown.append({})
|
|
63
|
+
|
|
64
|
+
strictEqual(result, markdown)
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
describe('.get', () => {
|
|
69
|
+
it('should be a method', () => {
|
|
70
|
+
const markdown = new Markdown()
|
|
71
|
+
|
|
72
|
+
strictEqual(typeof markdown.get, 'function')
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('should return the block with the matching header', () => {
|
|
76
|
+
const markdown = new Markdown()
|
|
77
|
+
.append({ header: 'abc' })
|
|
78
|
+
.append({ header: 'def' })
|
|
79
|
+
|
|
80
|
+
const result = markdown.get('def')
|
|
81
|
+
|
|
82
|
+
strictEqual(result.header, 'def')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('should return undefined if no matching block was found', () => {
|
|
86
|
+
const markdown = new Markdown()
|
|
87
|
+
|
|
88
|
+
const result = markdown.get('def')
|
|
89
|
+
|
|
90
|
+
strictEqual(typeof result, 'undefined')
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
describe('.parse', () => {
|
|
95
|
+
it('should be a method', () => {
|
|
96
|
+
const markdown = new Markdown()
|
|
97
|
+
|
|
98
|
+
strictEqual(typeof markdown.parse, 'function')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('should parse the given content', () => {
|
|
102
|
+
const markdown = new Markdown()
|
|
103
|
+
|
|
104
|
+
markdown.parse(examples.multiBlock.content)
|
|
105
|
+
|
|
106
|
+
strictEqual(markdown.blocks[0].header, examples.multiBlock.blocks[0].header)
|
|
107
|
+
strictEqual(markdown.blocks[0].level, examples.multiBlock.blocks[0].level)
|
|
108
|
+
deepStrictEqual(markdown.blocks[0].lines, examples.multiBlock.blocks[0].lines)
|
|
109
|
+
|
|
110
|
+
strictEqual(markdown.blocks[1].header, examples.multiBlock.blocks[1].header)
|
|
111
|
+
strictEqual(markdown.blocks[1].level, examples.multiBlock.blocks[1].level)
|
|
112
|
+
deepStrictEqual(markdown.blocks[1].lines, examples.multiBlock.blocks[1].lines)
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
describe('static .load', () => {
|
|
117
|
+
it('should be a static method', () => {
|
|
118
|
+
strictEqual(typeof Markdown.load, 'function')
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('should parse the given file', async () => {
|
|
122
|
+
const markdown = await Markdown.load('./test/support/multiBlock.md')
|
|
123
|
+
|
|
124
|
+
strictEqual(markdown.blocks[0].header, examples.multiBlock.blocks[0].header)
|
|
125
|
+
strictEqual(markdown.blocks[0].level, examples.multiBlock.blocks[0].level)
|
|
126
|
+
deepStrictEqual(markdown.blocks[0].lines, examples.multiBlock.blocks[0].lines)
|
|
127
|
+
|
|
128
|
+
strictEqual(markdown.blocks[1].header, examples.multiBlock.blocks[1].header)
|
|
129
|
+
strictEqual(markdown.blocks[1].level, examples.multiBlock.blocks[1].level)
|
|
130
|
+
deepStrictEqual(markdown.blocks[1].lines, examples.multiBlock.blocks[1].lines)
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
})
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { strictEqual } from 'node:assert'
|
|
2
|
+
import { describe, it } from 'mocha'
|
|
3
|
+
import Processor from '../lib/Processor.js'
|
|
4
|
+
import * as examples from './support/examples.js'
|
|
5
|
+
|
|
6
|
+
describe('Processor', () => {
|
|
7
|
+
it('should be a constructor', () => {
|
|
8
|
+
strictEqual(typeof Processor, 'function')
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('should assign the given path argument', () => {
|
|
12
|
+
const path = {}
|
|
13
|
+
const processor = new Processor({ path })
|
|
14
|
+
|
|
15
|
+
strictEqual(processor.path, path)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('should assign process.cwd() to the path property if no argument is given', () => {
|
|
19
|
+
const processor = new Processor()
|
|
20
|
+
|
|
21
|
+
strictEqual(processor.path, process.cwd())
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
describe('.process', () => {
|
|
25
|
+
it('should be a method', () => {
|
|
26
|
+
const processor = new Processor()
|
|
27
|
+
|
|
28
|
+
strictEqual(typeof processor.process, 'function')
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('should process all imports', async () => {
|
|
32
|
+
const processor = new Processor()
|
|
33
|
+
|
|
34
|
+
const result = await processor.process('./test/support/multiImports.md')
|
|
35
|
+
|
|
36
|
+
strictEqual(result, examples.multiImports.content)
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
})
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const multiBlock = (() => {
|
|
2
|
+
const blocks = [{
|
|
3
|
+
header: 'Header 1',
|
|
4
|
+
level: '#',
|
|
5
|
+
lines: [
|
|
6
|
+
'# Header 1',
|
|
7
|
+
'First line of the body of header 1',
|
|
8
|
+
'Second line of the body of header 1'
|
|
9
|
+
]
|
|
10
|
+
}, {
|
|
11
|
+
header: 'Header 1.1',
|
|
12
|
+
level: '##',
|
|
13
|
+
lines: [
|
|
14
|
+
'## Header 1.1',
|
|
15
|
+
'First line of the body of header 1.1',
|
|
16
|
+
'Second line of the body of header 1.1'
|
|
17
|
+
]
|
|
18
|
+
}]
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
blocks,
|
|
22
|
+
content: [
|
|
23
|
+
blocks[0].lines.join('\n'),
|
|
24
|
+
blocks[1].lines.join('\n')
|
|
25
|
+
].join('\n')
|
|
26
|
+
}
|
|
27
|
+
})()
|
|
28
|
+
|
|
29
|
+
const multiImports = (() => {
|
|
30
|
+
const blocks = [
|
|
31
|
+
...multiBlock.blocks,
|
|
32
|
+
{
|
|
33
|
+
header: 'Header 2',
|
|
34
|
+
level: '#',
|
|
35
|
+
lines: [
|
|
36
|
+
'# Header 2',
|
|
37
|
+
'First line of the body of header 2',
|
|
38
|
+
'Second line of the body of header 2'
|
|
39
|
+
]
|
|
40
|
+
}, {
|
|
41
|
+
header: 'Header 2.1',
|
|
42
|
+
level: '##',
|
|
43
|
+
lines: [
|
|
44
|
+
'## Header 2.1',
|
|
45
|
+
'First line of the body of header 2.1',
|
|
46
|
+
'Second line of the body of header 2.1'
|
|
47
|
+
]
|
|
48
|
+
}]
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
blocks,
|
|
52
|
+
content: [
|
|
53
|
+
blocks[0].lines.join('\n'),
|
|
54
|
+
blocks[1].lines.join('\n'),
|
|
55
|
+
blocks[2].lines.join('\n'),
|
|
56
|
+
blocks[3].lines.join('\n')
|
|
57
|
+
].join('\n')
|
|
58
|
+
}
|
|
59
|
+
})()
|
|
60
|
+
|
|
61
|
+
export {
|
|
62
|
+
multiBlock,
|
|
63
|
+
multiImports
|
|
64
|
+
}
|