make-me-a-content
TypeScript icon, indicating that this package has built-in type declarations

0.3.0 • Public • Published

make-me-a-content

npm version install size Coverage Status

mmac allows you to have templated sections in your source code and documentation.

It is heavily inspired by how Rome generates docs and source code.

Installation

npm install -D make-me-a-content

Example

Let's take a look at a file where there can be a large amount of templated content. The imports and the exported object are extremely repetitive. It makes sense to generate this section to avoid human error.

/* GENERATED_START(id:main;hash:sldkjflj425l26k45nl2kn54k6b2) This is generated content, do not modify by hand, to regenerate run "npm run build-docs" */
import bar from './things/bar.js'
import foo from './things/foo.js'
 
export const certainItems = {
    [bar.name]: bar,
    [foo.name]: foo,
}
/* GENERATED_END(id:main) */

Also the documentation where the same items need to be referenced.

Readme content
 
<!-- GENERATED_START(id:main;hash:sldkjflj425l26k45nl2kn54k6b2) This is generated content, do not modify by hand, to regenerate run "npm run build-docs" -->
| title          | description              | default value |
| :------------- | :----------------------: | ------------: |
|  Bar           | why you should use bar   |  default val  |
|  Foo           | why you should use foo   |  default val  |
<!-- GENERATED_END(id:main) -->
 
More content

Generation script

// scripts/update-docs.js
 
import fs from 'fs'
import path from 'path'
import {mmac} from 'make-me-a-content'
 
async function updateScripts() {
    const thingsDirContents = await fs.promises.readdir('./path/to/things') // ['foo.js', 'bar.js']
 
    // --- Source code
    const newSourceCodeContent = [
        ...thingsDirContents.map(
            filename => `import ${path.parse(filename).name} from './${filename}'`
        ),
        '', // to have an empty line in the output
        `const certainItems = {`
        ...thingsDirContents.map(
            filename => `    [${path.parse(filename).name}.name]: ${path.parse(filename).name}},`
        ),
        `}`
    ]
 
    await mmac({
        filepath: './path/to/somefile.js',
        lines: newSourceCodeContent,
        updateScript: 'npm run update-docs',
    })
 
    // --- Documentation
    const modules = await thingsDirContents.map(filename => import(`./path/to/things/${filename}`))
    const newDocsContent = [
        '| title          | description              | default value |',
        '| :------------- | :----------------------: | ------------: |',
        ...modules.map(m => `${m.name} | ${m.description} | ${m.defaultValue} |`)
    ]
 
    await mmac({
        filepath: './path/to/README.md',
        lines: newDocsContent,
        updateScript: 'npm run update-docs',
    })
}
 
updateScripts()

package.json

{
    "name": "your project",
    "scripts": {
        "update-docs": "node ./scripts/update-docs",
        "start": "node ./src/index.js"
    }
}

Usage

import {mmac} from 'make-me-a-content'
 
mmac({
    updateScript: 'npm run update-docs',
    filepath: './path/to/file.ext',
    lines: ['new content', 'to be inserted', 'between', 'marks']
})

Options

  • filepath path to a file to be updated
  • updateScript script to be run in your project to regenerate this section
  • lines content to be put between the marks
  • id to be user in content marks, optional, default is main
  • hash to be used in start mark, optional, default is md5 hash generated from the lines
  • comments add new comments by a file extension or overwrite existing ones
  • transform modify the new file content

Check for unstaged files

If you think of generating content for your project, you probably want to make sure that the content is always up to date. You can do this by calling mmac-check in a precommit and/or a CI check. You should call it directly after your content generation scripts. The script in your package.json should look similar to below.

{
    "name": "project-name",
    "scripts": {
        "generate-content": "node ./scripts/update-docs.js && mmac-check",
    }
}

Alternatively you can check for unstaged files yourself using a provided checkUnstaged function.

import {mmac, checkUnstaged} from 'make-me-a-content'
 
function main() {
    const updateScript = 'npm run generate-content'
 
    mmac({updateScript, /* ... */})
 
    const files = checkUnstaged()
 
    if (files.length > 0) {
        console.log(`Unstaged files, run "${updateScript}" locally and commit the changes`)
        process.exit(1)
    }
}

FAQ

The very first generation

Make sure you have added the start and end marks to the file where you want to insert the content. Ie

/* GENERATED_START(id:main;hash) */
/* GENERATED_END(id:main) */

How to format or prettify the content?

If you wish to also prettify file using eslint/prettier or another tool, you can use the transform option.

import {mmac} from 'make-me-a-content'
import prettier from 'prettier'
 
mmac({
    updateScript: 'npm run update-docs',
    filepath: './path/to/file.ext',
    lines: ['new content'],
    transform: newContent => prettier.format(newContent, {/* prettier options */})
})

How to have multiple templated sections in a single file?

To do that you can provide a different id per each section. The default one is "main". Example:

import {mmac} from 'make-me-a-content'
 
mmac({
    id: 'foo',
    updateScript: 'npm run update-docs',
    filepath: './path/to/file.ext',
    lines: ['foo content'],
})
 
mmac({
    id: 'bar',
    updateScript: 'npm run update-docs',
    filepath: './path/to/file.ext',
    lines: ['bar content'],
})

Why is updateScript not optional?

Having the comment about the content being generated and the script to update it lowers the learning curve for people seeing it for the first time.

Add or change comments for other file extensions

You can overwrite comments per file extension using the comments options

mmac({
    comments: {
        // overwrite javascript comments to use single line comment
        ".js": {
            start: "// ",
            end: "",
        },
        // support lua files
        ".lua": {
            start: "-- ",
            end: "",
        },
    },
    // other mmac options
})

Readme

Keywords

Package Sidebar

Install

npm i make-me-a-content

Weekly Downloads

18

Version

0.3.0

License

MIT

Unpacked Size

15.2 kB

Total Files

6

Last publish

Collaborators

  • antonk52