transpile-md-to-json
Version:
Transpile multiple markdown files to a single JSON file.
282 lines (245 loc) • 10.6 kB
Markdown
# transpile-md-to-json
## Transpile multiple markdown files to a single JSON file.
This project was developed to transpile all markdown files in a given folder (recursively) to a single JSON file which can be imported in [React](https://reactjs.org/) and supplied to [react-markdown](https://www.npmjs.com/package/react-markdown).
## Features
- Super simple to use
- Uses trusted dependencies ([chalk](https://www.npmjs.com/package/chalk), [chokidar](https://www.npmjs.com/package/chokidar), [commander](https://www.npmjs.com/package/commander), etc…)
- Very light codebase to audit
- Written in TypeScript
## Installation
```shell
npm install transpile-md-to-json -g
```
## Usage
```console
$ transpile-md-to-json -h
Usage: transpile-md-to-json [options]
Options:
--src <source> path to content folder
--dest <destination> path to JSON file
--ignore <ignore...> paths to ignore
--slugify slugify folder and file names
--flatten flatten nested properties
--blogify enable slugify and flatten and parse metadata
--git include last Git commit date
--watch watch source for changes
-h, --help display help for command
```
For [CRA](https://www.npmjs.com/package/create-react-app) projects, consider using [concurrently](https://www.npmjs.com/package/concurrently) to run both `start` and `transpile` scripts concurrently using `npm run code`.
```json
{
"scripts": {
"start": "react-scripts start",
"transpile": "transpile-md-to-json --src src/content --dest src/content.json --watch",
"code": "concurrently -n start,transpile npm:start npm:transpile"
}
}
```
Notice the `--watch` argument? This runs `transpile-md-to-json` in the background, transpiling markdown files as they are created, edited and deleted.
## Examples
**Transpile markdown files in [examples/content](examples/content) to JSON and output result to `stdout`**
```console
$ transpile-md-to-json --src examples/content
{
"fr": {
"foo": "<!--\nTitle: Ceci est un test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Ceci est un test\n"
},
"es": {
"foo": "<!--\nTitle: Esto es una prueba\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Esto es una prueba\n"
},
"en": {
"foo bar": "<!--\nTitle: This is another file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is another file name test\n",
"foo": "<!--\nTitle: This is a test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned: 1\n-->\n\n# This is a test\n",
"a": {
"b": {
"Hello world!": "<!--\nTitle: This is a file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is a file name test\n"
}
}
}
}
```
**Transpile markdown files in [examples/content](examples/content) to JSON ignoring `es` and `en/foo bar.md` paths and output result to `stdout`**
```console
$ transpile-md-to-json --src examples/content --ignore es --ignore "en/foo bar.md"
{
"fr": {
"foo": "<!--\nTitle: Ceci est un test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Ceci est un test\n"
},
"en": {
"foo": "<!--\nTitle: This is a test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned: 1\n-->\n\n# This is a test\n",
"a": {
"b": {
"Hello world!": "<!--\nTitle: This is a file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is a file name test\n"
}
}
}
}
```
**Transpile markdown files in [examples/content](examples/content) to JSON and write result to [examples/content.json](examples/content.json)**
```console
$ transpile-md-to-json --src examples/content --dest examples/content.json
Transpiling…
Transpiled successfully!
$ cat examples/content.json
{
"fr": {
"foo": "<!--\nTitle: Ceci est un test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Ceci est un test\n"
},
"es": {
"foo": "<!--\nTitle: Esto es una prueba\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Esto es una prueba\n"
},
"en": {
"foo bar": "<!--\nTitle: This is another file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is another file name test\n",
"foo": "<!--\nTitle: This is a test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned: 1\n-->\n\n# This is a test\n",
"a": {
"b": {
"Hello world!": "<!--\nTitle: This is a file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is a file name test\n"
}
}
}
}
```
**Transpile and slugify markdown files in [examples/content](examples/content) to JSON and write result to [examples/content-slugify.json](examples/content-slugify.json)**
```console
$ transpile-md-to-json --src examples/content --dest examples/content-slugify.json --slugify
Transpiling…
Transpiled successfully!
$ cat examples/content-slugify.json
{
"fr": {
"foo": "<!--\nTitle: Ceci est un test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Ceci est un test\n"
},
"es": {
"foo": "<!--\nTitle: Esto es una prueba\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Esto es una prueba\n"
},
"en": {
"foo-bar": "<!--\nTitle: This is another file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is another file name test\n",
"foo": "<!--\nTitle: This is a test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned: 1\n-->\n\n# This is a test\n",
"a": {
"b": {
"hello-world": "<!--\nTitle: This is a file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is a file name test\n"
}
}
}
}
```
**Transpile and flatten markdown files in [examples/content](examples/content) to JSON and write result to [examples/content-flatten.json](examples/content-flatten.json)**
```console
$ transpile-md-to-json --src examples/content --dest examples/content-flatten.json --flatten
Transpiling…
Transpiled successfully!
$ cat examples/content-flatten.json
{
"fr.foo": "<!--\nTitle: Ceci est un test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Ceci est un test\n",
"es.foo": "<!--\nTitle: Esto es una prueba\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Esto es una prueba\n",
"en.foo-bar": "<!--\nTitle: This is another file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is another file name test\n",
"en.foo": "<!--\nTitle: This is a test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned: 1\n-->\n\n# This is a test\n",
"en.a.b.hello-world": "<!--\nTitle: This is a file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is a file name test\n"
}
```
**Transpile and blogify markdown files in [examples/content](examples/content) to JSON and write result to [examples/content-blogify.json](examples/content-blogify.json)**
The `id` property is derived from dot path (`fr.foo` for example) using a [MD5](https://en.wikipedia.org/wiki/MD5) hash function.
The `metadata` property is derived from comment block (if present, see [examples/fr/foo.md](examples/content/fr/foo.md)).
Each line is parsed using `/([^:]+): ?(.+)?/` and keys are slugified and converted to camel case.
```console
$ transpile-md-to-json --src examples/content --dest examples/content-blogify.json --blogify --git
Transpiling…
Transpiled successfully!
$ cat examples/content-blogify.json
{
"fr.foo": {
"id": "f5fdbc126cb1a123fe8d60297803ea4f",
"path": "fr/foo.md",
"dirname": "fr",
"basename": "foo.md",
"createdOn": "2020-11-10T12:23:38.000Z",
"modifiedOn": "2023-08-28T13:20:37.940Z",
"git": {
"lastCommitOn": "2023-08-28T13:34:58.000Z",
"numberOfCommits": 3
},
"metadata": {
"title": "Ceci est un test",
"publicationDate": "2020-03-03T14:15:23.676Z",
"pinned": ""
},
"content": "<!--\nTitle: Ceci est un test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Ceci est un test\n"
},
"es.foo": {
"id": "94ced16505d73afe6cb2f7528b81f351",
"path": "es/foo.md",
"dirname": "es",
"basename": "foo.md",
"createdOn": "2020-11-10T12:23:38.000Z",
"modifiedOn": "2023-08-28T13:20:35.017Z",
"git": {
"lastCommitOn": "2023-08-28T13:34:58.000Z",
"numberOfCommits": 2
},
"metadata": {
"title": "Esto es una prueba",
"publicationDate": "2020-03-03T14:15:23.676Z",
"pinned": ""
},
"content": "<!--\nTitle: Esto es una prueba\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# Esto es una prueba\n"
},
"en.foo-bar": {
"id": "648d2a8192ed79e49ab9d460a94587af",
"path": "en/foo bar.md",
"dirname": "en",
"basename": "foo bar.md",
"createdOn": "2021-11-20T11:27:45.212Z",
"modifiedOn": "2023-08-28T13:20:29.052Z",
"git": {
"lastCommitOn": "2023-08-28T13:34:58.000Z",
"numberOfCommits": 4
},
"metadata": {
"title": "This is another file name test",
"publicationDate": "2020-03-03T14:15:23.676Z",
"pinned": ""
},
"content": "<!--\nTitle: This is another file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is another file name test\n"
},
"en.foo": {
"id": "08e72796bf9fe05dabdc6131a620deaa",
"path": "en/foo.md",
"dirname": "en",
"basename": "foo.md",
"createdOn": "2021-11-20T11:57:28.840Z",
"modifiedOn": "2023-08-28T13:20:21.794Z",
"git": {
"lastCommitOn": "2023-08-28T13:34:58.000Z",
"numberOfCommits": 4
},
"metadata": {
"title": "This is a test",
"publicationDate": "2020-03-03T14:15:23.676Z",
"pinned": "1"
},
"content": "<!--\nTitle: This is a test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned: 1\n-->\n\n# This is a test\n"
},
"en.a.b.hello-world": {
"id": "44989b6900829b8bfe748c4bca408761",
"path": "en/a/b/Hello world!.md",
"dirname": "en/a/b",
"basename": "Hello world!.md",
"createdOn": "2020-11-10T12:23:38.000Z",
"modifiedOn": "2023-08-28T13:20:25.647Z",
"git": {
"lastCommitOn": "2023-08-28T13:34:58.000Z",
"numberOfCommits": 4
},
"metadata": {
"title": "This is a file name test",
"publicationDate": "2020-03-03T14:15:23.676Z",
"pinned": ""
},
"content": "<!--\nTitle: This is a file name test\nPublication date: 2020-03-03T14:15:23.676Z\nPinned:\n-->\n\n# This is a file name test\n"
}
}
```
## Contributors
[Sun Knudsen](https://sunknudsen.com/)
## Licence
MIT