Auto toc generation and file injection, in place, for github flavored markdown.
MIT License
CAUTION: To avoid unintentional irreversible loss of sections of your markdown file, read and understand the documentation before using this node module. The library is not battle tested. Use on your own risk. However I have personally used it to create the
README.md
files of my own projects and have not encountered any unwanted results.
npm install --save-dev md-in-place
Node.js CLI executable that enables imports for markdown files.
Testing code coverage is around 90%.
Create a new folder and set it as your current working directory:
mkdir example; cd ./example;
Initialize the folder as an npm package and install md-in-place
as a development dependency:
npm init -y;
npm install --save-dev md-in-place;
Create the file ./README.md
with the following content:
# Example
## Table of contents
<!--#region toc-->
<!--#endregion toc-->
## Documentation
<!--#region my-custom-keyword ./documentation.md-->
<!--#endregion my-custom-keyword-->
<!--#region my-other-custom-keyword !./documentation.ts-->
<!--#endregion my-other-custom-keyword-->
Create the file ./documentation.ts
with the following content:
export const a: number = 1;
Create the file ./documentation.md
with the following content:
Hello world!
Execute:
npx md-in-place
Now the ./README.md
file should have the following content:
# Example
## Table of contents
<!--#region toc-->
- [Table of contents](#table-of-contents)
- [Documentation](#documentation)
<!--#endregion toc-->
## Documentation
<!--#region my-custom-keyword ./documentation.md-->
Hello world!
<!--#endregion my-custom-keyword-->
<!--#region my-other-custom-keyword !./documentation.ts-->
```ts
export const a: number = 1;
```
<!--#endregion my-other-custom-keyword-->
Use:
npx md-in-place --help
to get the cli documentation:
CLI syntax:
md-in-place mdInPlace? [[--<option> | -<flag>] <value>]#
Description:
Injects in place the provided github flavoured markdown, with file imports
and auto generated toc.
Non required options:
-i --input : string = "./README.md" Path to the markdown file.
The place to inject the auto generated toc is specified via special HTML comments:
CAUTION: Everything between these two comments gets irreversibly deleted on toc injection.
<!--#region toc-->
<!--#endregion toc-->
Both markdown and HTML headings are taken into account when creating the toc.
Headings inside markdown or HTML code blocks are ignored.
Headings from imported files are also taken into account.
The place to inject an imported file is specified via special HTML comments:
CAUTION: Everything between these two comments gets irreversibly deleted on file injection.
<!--#region keyword ./relative/path/to/file-->
<!--#endregion keyword-->
The keyword
can be any word you choose as long as the starting and ending comment have the same keyword.
For relative path that starts with exclamation mark:
<!--#region keyword !./relative/path/to/file-->
<!--#endregion keyword-->
the injected file is wrapped in markdown code block (the one with the three back ticks) with the same extension as the injected file extension. Adding more exclamation marks will add more back ticks. This is something useful when the injected file is a markdown file with code blocks.
If any markdown or html link has relative path, the program will throw error. The idea behind that is that relative links will not work for both npm and and github.
The special comments are not deleted after injection. This enables re-injection after you have updated something.
Special comments can not wrap other special comments.
Special comments inside html and markdown code blocks are ignored.
If there is something wrong with the special comments (keywords not matching, missing starting or ending comment, etc.), the program throws error without injecting.
The special comments can be collapsed in vscode. Keep them always collapsed to avoid editing their content.
Add two empty lines before and after each special comment.
Good
<!--#region toc-->
<!--#endregion toc-->
Bad
<!--#region toc-->
<!--#endregion toc-->
Try to use the program only at the distribution stage. Avoid using it in the development stage.
After you have edited the markdown file, make sure you have saved it before using the program.
I am open to suggestions/pull request to improve this program.
You will find the following commands useful:
Clones the github repository of this project:
git clone https://github.com/lillallol/md-in-place
Installs the node modules (nothing will work without them):
npm install
Tests the code and generates code coverage:
npm run test
The generated code coverage is saved in ./coverage
.
Lints the source folder using typescript and eslint:
npm run lint
Builds the typescript code from the ./src
folder to javascript code in ./dist
:
npm run build-ts
Creates the CLI executable of this program in ./bin/bin.js
:
npm run build-bin
Make sure that the ./dist
exists when you execute this command, otherwise it will not work.
Injects in place the generated toc and imported files to README.md
:
npm run build-md
Make sure that ./bin/bin.js
exists when you execute this command, otherwise it will not work.
Checks the project for spelling mistakes:
npm run spell-check
Take a look at the related configuration ./cspell.json
.
Checks ./src
for dead typescript files:
npm run dead-files
Take a look at the related configuration ./unimportedrc.json
.
The markdown file is parsed to abstract syntax tree (ast) using remark. The ast consists of markdown and html fragments that include information such as:
The markdown fragments are converted to html and together with the rest of the html fragments are searched using jsdom, for anchor tags, comments and headings.
Validation for:
is too strict. Open an issue so I can improve it.
Empty lines define the beginning and end of html fragments. That can potentially lead to unexpected results. For example this markdown fragment:
<details>
<summary>Some summary</summary>
</details>
is parsed as a single html fragment, while this:
<details>
<summary>Some summary</summary>
</details>
is parsed as two html fragments because of the line that separates them.
I have already written the code for such a feature, but I have disabled it. That is because the margins of such a toc are not uniform. If people still show interest I am willing to enable this feature.
This program would not be possible without remark and jsdom.
bug fixes
breaking changes
fn-to-cli
version. That means that now instead of passing "./path/to/markdown.md"
, you have to pass "'./path/to/markdown.md'"
.non breaking changes
bug fixes
other
README.md
non breaking changes:
non breaking changes:
The program now works for indented comments. Here is an example:
- a list
<!--#region toc-->
<!--#endregion toc-->
You can add more than one exclamation mark in the relative path of the file to be injected, if you want to wrap it with more than three back ticks. This is useful when you inject a markdown file that has code blocks.
bug fixes:
fn-to-cli
from dev dependencies to dependencies.MIT