1 | # Markdown Magic [![npm-version][npm-badge]][npm-link]
|
2 |
|
3 | ✨ Add a little magic to your markdown ✨
|
4 |
|
5 | ## About
|
6 |
|
7 | <img align="right" width="200" height="183" src="https://cloud.githubusercontent.com/assets/532272/21507867/3376e9fe-cc4a-11e6-9350-7ec4f680da36.gif">Markdown magic uses comment blocks in markdown files to automatically sync or transform its contents.
|
8 |
|
9 | - Automatically keep markdown files up to date from local or remote code sources
|
10 | - Transform markdown content with custom transform functions
|
11 | - Render markdown with any template engine
|
12 | - Automatically generate a table of contents
|
13 | - ... etc
|
14 |
|
15 | The comments markdown magic uses are hidden in markdown and when viewed as HTML.
|
16 |
|
17 | This `README.md` is generated with `markdown-magic` [view the raw file](https://raw.githubusercontent.com/DavidWells/markdown-magic/master/README.md) to see how.
|
18 |
|
19 | [Video demo](http://www.youtube.com/watch?v=4V2utrvxwJ8) • [Example Repo](https://github.com/DavidWells/repo-using-markdown-magic)
|
20 |
|
21 | ## Table of Contents
|
22 |
|
23 | <details>
|
24 | <summary>Click to expand</summary>
|
25 |
|
26 | - [About](#about)
|
27 | - [Install](#install)
|
28 | - [Usage](#usage)
|
29 | * [API](#api)
|
30 | * [Configuration Options](#configuration-options)
|
31 | - [CLI Usage](#cli-usage)
|
32 | - [Transforms](#transforms)
|
33 | * [CODE](#code)
|
34 | * [REMOTE](#remote)
|
35 | * [TOC](#toc)
|
36 | - [Running Async transforms](#running-async-transforms)
|
37 | - [🔌 Third Party Plugins](#%F0%9F%94%8C-third-party-plugins)
|
38 | - [Adding Custom Transforms](#adding-custom-transforms)
|
39 | - [Plugin Example](#plugin-example)
|
40 | - [Other usage examples](#other-usage-examples)
|
41 | - [Custom Transform Demo](#custom-transform-demo)
|
42 | - [Prior Art](#prior-art)
|
43 | - [License](#license)
|
44 |
|
45 | </details>
|
46 |
|
47 |
|
48 | ## Install
|
49 |
|
50 | ```bash
|
51 | npm install markdown-magic --save-dev
|
52 | ```
|
53 |
|
54 | ## Usage
|
55 |
|
56 |
|
57 | ```js
|
58 | import path from 'path'
|
59 | import markdownMagic from 'markdown-magic'
|
60 |
|
61 | const markdownPath = path.join(__dirname, 'README.md')
|
62 | markdownMagic(markdownPath)
|
63 | ```
|
64 |
|
65 |
|
66 |
|
67 |
|
68 | - Do not remove or modify this section -->
|
69 | ### API
|
70 | ```js
|
71 | markdownMagic(filePath, config, callback)
|
72 | ```
|
73 | - `filePaths` - *String or Array* - Path or glob pattern. Uses [globby patterns](https://github.com/sindresorhus/multimatch/blob/master/test.js)
|
74 | - `config` - See configuration options below
|
75 | - `callback` - callback to run after markdown updates
|
76 |
|
77 |
|
78 |
|
79 | - Do not remove or modify this section -->
|
80 | ### Configuration Options
|
81 |
|
82 | - `transforms` - *object* - (optional) Custom commands to transform block contents, see transforms & custom transforms sections below.
|
83 |
|
84 | - `outputDir` - *string* - (optional) Change output path of new content. Default behavior is replacing the original file
|
85 |
|
86 | - `matchWord` - *string* - (optional) Comment pattern to look for & replace inner contents. Default `AUTO-GENERATED-CONTENT`
|
87 |
|
88 | - `DEBUG` - *Boolean* - (optional) set debug flag to `true` to inspect the process
|
89 |
|
90 |
|
91 | ## CLI Usage
|
92 |
|
93 | You can use `markdown-magic` as a CLI command. Run `markdown --help` to see all available CLI options
|
94 |
|
95 | ```bash
|
96 | markdown --help
|
97 | # or
|
98 | md-magic
|
99 | ```
|
100 |
|
101 | This is useful for adding the package quickly to your `package.json` npm scripts
|
102 |
|
103 | CLI usage example with options
|
104 |
|
105 | ```bash
|
106 | md-magic --path '**/*.md' --config ./config.file.js
|
107 | ```
|
108 |
|
109 | In NPM scripts, `npm run docs` would run the markdown magic and parse all the `.md` files in the directory.
|
110 |
|
111 | ```json
|
112 | "scripts": {
|
113 | "docs": "md-magic --path '**/*.md' --ignore 'node_modules'"
|
114 | },
|
115 | ```
|
116 |
|
117 | If you have a `markdown.config.js` file where `markdown-magic` is invoked, it will automatically use that as the configuration unless otherwise specified by `--config` flag.
|
118 |
|
119 |
|
120 |
|
121 | ```js
|
122 | /* CLI markdown.config.js file example */
|
123 | module.exports = {
|
124 | transforms: {
|
125 | /* Match <!-- AUTO-GENERATED-CONTENT:START (LOLZ) --> */
|
126 | LOLZ(content, options) {
|
127 | return `This section was generated by the cli config markdown.config.js file`
|
128 | }
|
129 | },
|
130 | callback: function () {
|
131 | console.log('done')
|
132 | }
|
133 | }
|
134 | ```
|
135 |
|
136 |
|
137 | ## Transforms
|
138 |
|
139 | Markdown Magic comes with a couple of built in transforms for you to use or you can extend it with your own transforms. See 'Custom Transforms' below.
|
140 |
|
141 |
|
142 | ### CODE
|
143 |
|
144 | Get code from file or URL and put in markdown
|
145 |
|
146 | **Options:**
|
147 | - `src`: The relative path to the code to pull in, or the `URL` where the raw code lives
|
148 | - `syntax` (optional): Syntax will be inferred by fileType if not specified
|
149 | - `header` (optional): Will add header comment to code snippet. Useful for pointing to relative source directory or adding live doc links
|
150 |
|
151 | **Example:**
|
152 | ```md
|
153 | <!-- AUTO-GENERATED-CONTENT:START (CODE:src=./relative/path/to/code.js) -->
|
154 | This content will be dynamically replaced with code from the file
|
155 | <!-- AUTO-GENERATED-CONTENT:END -->
|
156 | ```
|
157 |
|
158 | Default `MATCHWORD` is `AUTO-GENERATED-CONTENT`
|
159 |
|
160 | ---
|
161 |
|
162 | ### REMOTE
|
163 |
|
164 | Get any remote Data and put in markdown
|
165 |
|
166 | **Options:**
|
167 | - `url`: The URL of the remote content to pull in
|
168 |
|
169 | **Example:**
|
170 | ```md
|
171 | <!-- AUTO-GENERATED-CONTENT:START (REMOTE:url=http://url-to-raw-md-file.md) -->
|
172 | This content will be dynamically replace from the remote url
|
173 | <!-- AUTO-GENERATED-CONTENT:END -->
|
174 | ```
|
175 |
|
176 | Default `MATCHWORD` is `AUTO-GENERATED-CONTENT`
|
177 |
|
178 | ---
|
179 |
|
180 | ### TOC
|
181 |
|
182 | Generate table of contents from markdown file
|
183 |
|
184 | **Options:**
|
185 | - `firsth1` - *boolean* - (optional): Show first h1 of doc in table of contents. Default `false`
|
186 | - `collapse` - *boolean* - (optional): Collapse the table of contents in a detail accordian. Default `false`
|
187 | - `collapseText` - *string* - (optional): Text the toc accordian summary
|
188 | - `excludeText` - *string* - (optional): Text to exclude in the table of contents. Default `Table of Contents`
|
189 |
|
190 | **Example:**
|
191 | ```md
|
192 | <!-- AUTO-GENERATED-CONTENT:START (TOC) -->
|
193 | toc will be generated here
|
194 | <!-- AUTO-GENERATED-CONTENT:END -->
|
195 | ```
|
196 |
|
197 | Default `MATCHWORD` is `AUTO-GENERATED-CONTENT`
|
198 |
|
199 | ---
|
200 |
|
201 |
|
202 |
|
203 | ## Running Async transforms
|
204 |
|
205 | Markdown magic was designed to work synchronously. Mainly for simplicity & because it's not a serverside app and speed is not really an issue.
|
206 |
|
207 | You can use async transforms too though! To use async transforms, you will need to force them into a sync mode. [Example](https://github.com/DavidWells/middy-example/blob/7f72fc1afaa8699daf8df77f7d50c0576859b261/scripts/docs.js#L3-L4)
|
208 |
|
209 | [Forcing async functions to run sync in node.js](https://davidwells.io/snippets/forcing-async-functions-to-sync-in-node/)
|
210 |
|
211 | Version 2.0 of markdown magic will likely be async first [see issue](https://github.com/DavidWells/markdown-magic/issues/3)
|
212 |
|
213 | ## 🔌 Third Party Plugins
|
214 |
|
215 | * [wordcount](https://github.com/DavidWells/markdown-magic-wordcount/) - Add wordcount to markdown files
|
216 | * [github-contributors](https://github.com/DavidWells/markdown-magic-github-contributors) - List out the contributors of a given repository
|
217 | * [directory-tree](https://github.com/camacho/markdown-magic-directory-tree) - Add directory tree to markdown files
|
218 | * [install-command](https://github.com/camacho/markdown-magic-install-command) - Add install command to markdown files with `peerDependencies` included
|
219 | * [subpackage-list](https://github.com/camacho/markdown-magic-subpackage-list) - Add list of all subpackages (great for projects that use [Lerna](https://github.com/lerna/lerna))
|
220 | * [version-badge](https://github.com/camacho/markdown-magic-version-badge) - Add a badge with the latest version of the project
|
221 | * [template](https://github.com/camacho/markdown-magic-template) - Add Lodash template support
|
222 | * [dependency-table](https://github.com/camacho/markdown-magic-dependency-table) - Add a table of dependencies with links to their repositories, version information, and a short description
|
223 | * [package-scripts](https://github.com/camacho/markdown-magic-package-scripts) - Add a table of `package.json` scripts with descriptions
|
224 | * [prettier](https://github.com/camacho/markdown-magic-prettier) - Format code blocks with [`prettier`](https://github.com/prettier/prettier)
|
225 | * [engines](https://github.com/camacho/markdown-magic-engines) - Print engines list from `package.json`
|
226 | * [jsdoc](https://github.com/bradtaylorsf/markdown-magic-jsdoc) - Adds jsdoc comment support
|
227 | * [build-badge](https://github.com/rishichawda/markdown-magic-build-badge) - Update branch badges to auto-magically point to current branches.
|
228 | * [package-json](https://github.com/forresst/markdown-magic-package-json) - Add the package.json properties to markdown files
|
229 | * [local-image](https://github.com/stevenbenisek/markdown-magic-local-image)
|
230 | * [figlet](https://github.com/lafourchette/markdown-magic-figlet) - Add FIGfont text to markdown files
|
231 | * [local-image](https://github.com/stevenbenisek/markdown-magic-local-image) - plugin to add local images to markdown
|
232 |
|
233 | ## Adding Custom Transforms
|
234 |
|
235 | Markdown Magic is extendable via plugins.
|
236 |
|
237 | Plugins allow developers to add new transforms to the `config.transforms` object. This allows for things like using different rendering engines, custom formatting, or any other logic you might want.
|
238 |
|
239 | Plugins run in order of registration.
|
240 |
|
241 | The below code is used to generate **this markdown file** via the plugin system.
|
242 |
|
243 |
|
244 |
|
245 | ```js
|
246 | const fs = require('fs')
|
247 | const path = require('path')
|
248 | const execSync = require('child_process').execSync
|
249 | const markdownMagic = require('../index') // 'markdown-magic'
|
250 |
|
251 | const config = {
|
252 | matchWord: 'MD-MAGIC-EXAMPLE', // default matchWord is AUTO-GENERATED-CONTENT
|
253 | transforms: {
|
254 | /* Match <!-- AUTO-GENERATED-CONTENT:START (customTransform:optionOne=hi&optionOne=DUDE) --> */
|
255 | customTransform(content, options) {
|
256 | console.log('original content in comment block', content)
|
257 | console.log('options defined on transform', options)
|
258 | // options = { optionOne: hi, optionOne: DUDE}
|
259 | return `This will replace all the contents of inside the comment ${options.optionOne}`
|
260 | },
|
261 | /* Match <!-- AUTO-GENERATED-CONTENT:START (RENDERDOCS:path=../file.js) --> */
|
262 | RENDERDOCS(content, options) {
|
263 | const fileContents = fs.readFileSync(options.path, 'utf8')
|
264 | const docBlocs = require('dox').parseComments(fileContents, { raw: true, skipSingleStar: true })
|
265 | let updatedContent = ''
|
266 | docBlocs.forEach((data) => {
|
267 | updatedContent += `${data.description.full}\n\n`
|
268 | })
|
269 | return updatedContent.replace(/^\s+|\s+$/g, '')
|
270 | },
|
271 | /* Match <!-- AUTO-GENERATED-CONTENT:START (pluginExample) --> */
|
272 | pluginExample: require('./plugin-example')({ addNewLine: true }),
|
273 | /* Plugins from npm */
|
274 | // count: require('markdown-magic-wordcount'),
|
275 | // github: require('markdown-magic-github-contributors')
|
276 | }
|
277 | }
|
278 |
|
279 | /* This example callback automatically updates Readme.md and commits the changes */
|
280 | const callback = function autoGitCommit(err, output) {
|
281 | // output is array of file information
|
282 | output.forEach(function(data) {
|
283 | const mdPath = data.outputFilePath
|
284 | if(!mdPath) return false
|
285 | const gitAdd = execSync(`git add ${mdPath}`, {}, (error) => {
|
286 | if (error) console.warn(error)
|
287 | const msg = `${mdPath} automatically updated by markdown-magic`
|
288 | const gitCommitCommand = `git commit -m '${msg}' --no-verify`
|
289 | execSync(gitCommitCommand, {}, (err) => {
|
290 | if (err) console.warn(err)
|
291 | console.log('git commit automatically ran. Push up your changes!')
|
292 | })
|
293 | })
|
294 | })
|
295 | }
|
296 |
|
297 | const markdownPath = path.join(__dirname, '..', 'README.md')
|
298 | markdownMagic(markdownPath, config, callback)
|
299 | ```
|
300 |
|
301 |
|
302 | ## Plugin Example
|
303 |
|
304 | Plugins must return a transform function with the following signature.
|
305 |
|
306 | ```js
|
307 | return function myCustomTransform (content, options)
|
308 | ```
|
309 |
|
310 |
|
311 |
|
312 | ```js
|
313 | /* Custom Transform Plugin example */
|
314 | const merge = require('deepmerge')
|
315 | module.exports = function customPlugin(pluginOptions) {
|
316 | // set plugin defaults
|
317 | const defaultOptions = {
|
318 | addNewLine: false
|
319 | }
|
320 | const userOptions = pluginOptions || {}
|
321 | const pluginConfig = merge(defaultOptions, userOptions)
|
322 | // return the transform function
|
323 | return function myCustomTransform (content, options) {
|
324 | const newLine = (pluginConfig.addNewLine) ? '\n' : ''
|
325 | const updatedContent = content + newLine
|
326 | return updatedContent
|
327 | }
|
328 | }
|
329 | ```
|
330 |
|
331 |
|
332 | [View the raw file](https://raw.githubusercontent.com/DavidWells/markdown-magic/master/README.md) file and run `npm run docs` to see this plugin run
|
333 |
|
334 | This content is altered by the `pluginExample` plugin registered in `examples/generate-readme.js`
|
335 |
|
336 |
|
337 |
|
338 | ## Other usage examples
|
339 |
|
340 | - [Serverless Plugin Repo](https://github.com/serverless/plugins/blob/master/generate-docs.js) this example takes a `json` file and converts it into a github flavored markdown table
|
341 | - [MochaJS](https://github.com/mochajs/mocha/blob/4cc711fa00f7166a2303b77bf2487d1c2cc94621/scripts/markdown-magic.config.js)
|
342 | - [tc39/agendas](https://github.com/tc39/agendas#agendas) - [code](https://github.com/tc39/agendas/blob/65945b1b6658e9829ef95a51bf2632ff44f951e6/scripts/generate.js)
|
343 | - [moleculerjs/moleculer-addons](https://github.com/moleculerjs/moleculer-addons/blob/7cf0f72140717c52621b724cd54a710517106df0/readme-generator.js)
|
344 | - [good-first-issue](https://github.com/bnb/good-first-issue/blob/e65513a1f26167dea3c137008b8796640d8d5303/markdown.config.js)
|
345 | - [navikt/nav-frontend-moduler](https://github.com/navikt/nav-frontend-moduler/blob/20ad521c27a43d3203eab4bc32121e5b8270c077/_scripts/generateReadmes.js)
|
346 | - [country-flags-svg](https://github.com/ronatskiy/country-flags-svg/blob/cfb2368c7e634ebc1679855e13cc3e26ca11187f/markdown.config.js)
|
347 | - [react-typesetting](https://github.com/exogen/react-typesetting/blob/7114cdc8c4cb1b0d59ebc8b5364e808687419889/markdown.config.js)
|
348 | - [and many more!](https://github.com/search?o=desc&p=1&q=markdown-magic+filename%3Apackage.json+-user%3Ah13i32maru+-user%3Aesdoc+-user%3Aes-doc&s=indexed&type=Code)
|
349 |
|
350 | ## Custom Transform Demo
|
351 |
|
352 | View the raw source of this `README.md` file to see the comment block and see how the `customTransform` function in `examples/generate-readme.js` works
|
353 |
|
354 |
|
355 | This will replace all the contents of inside the comment DUDE
|
356 |
|
357 |
|
358 | ## Prior Art
|
359 |
|
360 | This was inspired by [Kent C Dodds](https://twitter.com/kentcdodds) and [jfmengels](https://github.com/jfmengels)'s [all contributors cli](https://github.com/jfmengels/all-contributors-cli) project.
|
361 |
|
362 |
|
363 | This section was generated by the cli config markdown.config.js file
|
364 |
|
365 |
|
366 | ## License
|
367 |
|
368 | [MIT][mit] © [DavidWells][author]
|
369 |
|
370 | [npm-badge]:https://img.shields.io/npm/v/markdown-magic.svg?style=flat-square
|
371 | [npm-link]: http://www.npmjs.com/package/markdown-magic
|
372 | [mit]: http://opensource.org/licenses/MIT
|
373 | [author]: http://github.com/davidwells
|