emdaer ·
- What is emdaer?
- Adding emdaer to your project
- How emdaer works
- Core Plugins
- Core Transforms
- Contributing
- This README
- License
What is emdaer?
emdaer lets you to use plugins and transforms within markdown files because READMEs (and other documentation) are crucial files that are often lackluster and/or incomplete and have a tendency to become stale
A couple use cases that illustrate the power of emdaer:
-
🤝 Keep it in sync Create templates for use across all of your organizations projects to promote synchronicity and reduce doing the same work over and over -
🗃 Keep it organized Keep your documentation DRY and organized by importing content from your codebase, splitting large documents into chunks, and formatting it with Prettier. -
🍋 Keep it fresh Ensure your documents stay up to date by pulling in new data from various sources with every build
Adding emdaer to your project
We recommend using emdaer with lint-staged and husky.
Install dependencies:
npm install --save-dev @emdaer/cli @emdaer/plugin-value-from-package lint-staged husky
or with yarn:
yarn add @emdaer/cli @emdaer/plugin-value-from-package lint-staged husky -D
Follow the lint-staged setup instructions.
{
"scripts": {
+ "emdaer": "emdaer && git add *.md",
+ "precommit": "lint-staged"
}
}
In your lint-staged config file add an entry for emdaer:
module.exports = {
'*.js': ['eslint --fix', 'prettier --write', 'git add'],
+ '*.emdaer.md': ['emdaer --yes', 'git add *.md'],
};
NOTE: In the case of a precommit
hook (or CI/other automation), we don’t want to be prompted about anything. The --yes
flag will automatically answer “yes” to any prompts. For example, it will make emdaer write your READMEs without prompting about overwritting direct changes to a destination README file.
Add a .emdaer/README.emdaer.md
file:
# <!--emdaer-p
- '@emdaer/plugin-value-from-package'
- value: name
-->
And give it a whirl:
npm run emdaer
When you commit your changes, lint-staged will run emdaer on any *.emdaer.md
files you may have changed.
Manual Usage
emdaer can be run manually against files by providing space separated file paths:
npm run emdaer -- .emdaer/README.emdaer.md .emdaer/CONTRIBUTING.emdaer.md
If emdaer is not provided a path, the default glob .emdaer/**/*.emdaer.md
is searched:
npm run emdaer
NOTE: By default, emdaer checks for existing changes to your READMEs before writing. If it detects changes, it will provide a prompt asking if you would like to overwrite the README with the newly generated content. If you accidentally edited the README directly, you will want to answer n
to the prompt, move any changes to the respective .emdaer/*.emdaer.md
file, and rerun emdaer. If you would like to discard those changes, answer Y
to the prompt or use the --yes
flag to skip the prompt all together. In both cases, emdaer will overwrite the README with the newly generated content.
How emdaer works
emdaer processes template files and writes the resulting files to your project.
We match .emdaer/(**/*).emdaer(.md)
and use the captured part of each matched file to determine the path for the output.
💡 Hint
In the case that you have an emdaer file in a nested directory inside the .emdaer
directory, emdaer will output the respective README in that directory in your code base. For example, .emdaer/src/components/README.emdaer.md
will output the generated README at src/components/README.emdaer.md
.
Plugins & Transforms
# <!--emdaer-p
- '@emdaer/plugin-value-from-package'
- value: name
-->
Hello, World!
<!--emdaer-p
- '@emdaer/plugin-import'
- path: './.emdaer/printThrice.js'
args:
- 'Hey'
-->
<!--emdaer-t
- '@emdaer/transform-prettier'
- options:
proseWrap: preserve
singleQuote: true
trailingComma: es5
-->
This example, once processed, will look something like this:
<h1>mypackage-name</h1>
<p>Hello, World!</p>
<p>Hey<br>Hey<br>Hey</p>
This example includes two plugin calls (emdaer-p
) and one transform call (emdaer-t
).
❓ Help
The first plugin call is to @emdaer/plugin-value-from-package. It is used to get the value ofname
frompackage.json
. That way if your project name change, so does your README.
The second plugin call is to @emdaer/plugin-import. It is used to import a function calledprintThrice
and executing it with the argumentHey
, printing it three times. Thepath
parameter can be any node modules that exports a string, exports a function that returns a string, or exports a funciton that returns a promise that resolves to a string.
The third emdaer call is to @emdaer/transform-prettier. It will format your README with the given options so you don’t have to.
Emdaer plugin/transform calls are just html comments. These calls take the form of yaml tuples where the first item is the name of the function to call and the second item is an options object that is passed to that function.
For plugins, the result of the call replaces the corresponding comment block.
For transforms, the function acts on the entire document and rewrites the entire file. In some cases, like @emdaer/transform-table-of-contents, transforms can inline their content, replacing the corresponding comment block.
Code Fences
Platforms vary in how they provide syntax highlighted code to users READMEs, rendering code fences with language specificers as HTML/CSS, each in their own way. Emdaer also transforms your README in HTML via marked to make it more portable.
Instead of trying to guess how platforms expect the HTML/CSS of a code fence to be output, when emdaer encounters a code fence with a language specified, it will ignore it. This means that while the rest of your README will be transformed to HTML, code fences will remain in Markdown. This sacrifices a bit of portability for the sake of readability and UX.
NOTE: If it’s important that your README be pure HTML, do not use language specifiers in your code fences.
Core Plugins
- @emdaer/plugin-contributors-details-github An emdaer plugin that gathers and renders contributor details from GitHub
- @emdaer/plugin-details An emdaer plugin that renders HTML5 details elements from which users can retrieve additional information
- @emdaer/plugin-documentation An emdaer plugin to generate documentation from your code comments using documentationjs
- @emdaer/plugin-image An emdaer plugin that renders HTML img elements
- @emdaer/plugin-import An emdaer plugin that imports content from another file
- @emdaer/plugin-jsdoc-tag-value An emdaer plugin that pulls values from a given function’s jsdoc comment
- @emdaer/plugin-license-reference An emdaer plugin that renders license information from the package
- @emdaer/plugin-link An emdaer plugin that renders anchor elements
- @emdaer/plugin-list An emdaer plugin that renders HTML list element.
- @emdaer/plugin-list-lerna-packages An emdaer plugin that generate a list of lerna packages in a project.
- @emdaer/plugin-shields An emdaer plugin that renders metadata badges for open source projects from shields.io
- @emdaer/plugin-table An emdaer plugin that renders HTML tables
- @emdaer/plugin-value-from-package An emdaer plugin that retrieves and renders values from package.json
Core Transforms
- @emdaer/transform-github-emoji An emdaer transformation that renders GitHub-flavored emoji codes
- @emdaer/transform-prettier An emdaer transformation that formats markdown, including code blocks, using prettier
- @emdaer/transform-table-of-contents An emdaer transformation that generates a table of contents
Contributing
If you’d like to make emdaer better, please read our guide to contributing.
This README
This README was generated with emdaer. However, it is special in that it shares its content with the emdaer website via the @emdaer/meta and @emdaer/plugin-import packages. @emdaer/meta exports each section of this README as a node module which @emdaer/plugin-import imports like so:
<!--emdaer-p
- '@emdaer/plugin-import'
- path: '@emdaer/meta/lib/README/this-readme.md'
-->
License
emdaer is MIT licensed.