documentative
a tool for precompiling docs from markdown
what is this? why use it?
there are a lot of tools out there for publishing websites and for generating documentation. some are really powerful - even to the extend of processing code and building docs straight from that. sometimes it's just simpler to write some markdown and publish it as a static site on github pages.
i was doing that a lot: and since i was writing markdown and then also manually building a matching website, i was spending nearly as much time on that as i was on coding the project itself. i had a reasonably solid template i was using already, so i did what leads many people to publishing things like this: i thought to myself 'how can i automate this?'
documentative cuts out half the work - you write the markdown; it builds you a responsive, modern website.
demo: https://dragonwocky.me/documentative/
features of a built site include...
- a responsive layout! mobile support is robust, with the sidebar transforming into a hamburger-triggered menu.
- light/dark mode that respects the user's system mode (with the capability to display a different icon depending on the mode).
- in-page navigation via #IDs (with a sidebar that scrolls to match the reader location), allowing for keeping your place on the page when you reload or linking to a specific section.
- social-media embed friendly.
- + y'know, like, being a configurably built site - you pick a primary colour, you define a footer, you choose which files are served or precompiled... etc.
usage
this package is available from the npm package registry.
npm i -s documentative
const docs = require('documentative');
to build/precompile to a directory
docs.build(inputdir, outputdir, options);
// returns a promise: resolves to true
| argument | type | value |
|---|---|---|
inputdir |
string | e.g. 'pages' |
outputdir |
string | e.g. 'build' |
options |
object | see #options |
if you wish your inputdir and outputdir to be the same,
that works too - just enable the overwrite option (see #options).
docs.build('.', '.', { overwrite: true });
to serve the directory from a local http server
docs.serve(inputdir, port, options);
// returns a promise: resolves to the started http server
| argument | type | value |
|---|---|---|
inputdir |
string | e.g. 'pages' |
port |
number | e.g. 8080 |
options |
object | see #options |
not recommended unless for testing purposes - especially if serving a larger directory, as it will re-read the entire directory for every file serve.
cli
if this is your preferred method of use, it is recommended to install via npm i -g documentative.
usage:
> documentative-build <inputdir> <outputdir>
e.g. documentative-build pages build
> documentative-serve <inputdir> [--port, -p PORT]
e.g. documentative-serve pages -p 3000
options:
--help, -h show this message
--port, -p set the HTTP server port used by documentative-serve
(default: 8080)
** to configure the process, place configuration options into
<inputdir>/docs.json
the
<inputdir>/docs.jsonfile will be added to the exclude list (see #options).
writing a page
pages are written in github flavoured markdown.
it is recommended to start every page with a # h1, as that is what is used
for the sidebar table-of-contents documentative generates.
in order to maintain viability of pages as both markdown and html, any local markdown page
links are changed to match page src -> output. e.g. a link written as [link](README.md)
may transformed to <a href='index.html'>link</a>.
check out the styling guide for ways to further customise what comes out.
options
{
title: string, // default: 'documentative'
primary: string/colour, // default: '#712c9c
git: string/url,
footer: string,
// default: '© 2020 someone, under the [MIT license](https://choosealicense.com/licenses/mit/).'
card: {
description: string,
url: string/url
},
icon: {
light: string/filepath,
dark: string/filepath
},
overwrite: boolean, // default: false
exclude: [strings/filepaths],
ignoredotfiles: boolean, // default: true
nav: []
}
git + footer
markdown can be used within the footer.
the git property defines the url to your inputdir on github or a similar site, excluding the file itself.
for github repos, the url must be https://github.com/user/repo/blob/<branch>/[folder/].
for gitlab, it must be https://gitlab.com/user/repo/-/blob/<branch>/[folder/].
e.g. your .md files are in a folder called docs @ the master branch of the repo https://github.com/myname/project/.
you would set the git property to https://github.com/myname/project/blob/master/nav.
then, if within the footer you wish to link to the hosted .md of the page, simply set it to:
"[Edit on Github](__git__)". the __git__ will be replaced by the config definition + the page source.
for the example above, when visiting page.html, the footer would link to https://github.com/myname/project/blob/master/nav/page.md.
if you wish to completely hide the footer,
simply set the following:
footer: '',
card
the card properties are used for the preview embeds/cards created by social media platforms
when linking to your page. the card.url should be the canonical base url for your site and must end with a /.
(e.g. https://example.com/ or https://dragonwocky.me/documentative/, but NOT https://dragonwocky.me/documentative/page.html)
icon
the light/dark icons will be shown dependent on whether the viewer has light/dark mode enabled. if only 1 of the icons is set (either light or dark), that icon will be shown for both modes.
overwrite
beware of turning on overwrite, as any files copied across from the inputdir will irreversibly overwrite files in the outputdir with conflicting names.
exclude
to exclude everything within a folder, end the exclude with /* (e.g. ignorethisdir/*).
any files within
node_modulesdirectories will always be excluded, regardless of inclusion in the above list.
ignoredotfiles
if true, will not build/serve any files or folders starting with a ..
the nav: default behaviour
- all markdown files are listed.
- nav entry names are the first header within the
.md, or the filename. - entries are sorted by alphabetical order,
though the
index.mdfile is always first. - if there is no
index.mdbut there is aREADME.md, it becomes the first in the order and is output asindex.html. - entries are categorised by directory (a title is added with the name of the directory).
the nav: custom behaviour
defining a title
strict definition:
{
type: 'title',
text: string // e.g. 'this is a title'
}
shorthand:
string,
// e.g. 'this is a title'
defining a page
strict definition:
{
type: 'page',
output: string/filepath, // e.g. 'getting-started.html'
src: string/filepath, // e.g. 'tutorial.md'
}
shorthand:
[output, src, git],
// e.g. ['getting-started.html', 'tutorial.md']
if the src is not a valid/existing file, it will be assumed to be a link.
defining a link
strict definition:
{
type: 'link',
text: string, // e.g. github
url: string/url // e.g. https://github.com/dragonwocky/documentative/
}
shorthand:
[text, url],
// e.g. ['github', 'https://github.com/dragonwocky/documentative/']
example nav
strict definition:
[
{ type: 'page', output: 'getting-started.html', input: 'tutorial.md' },
{ type: 'title', text: 'resources' },
{
type: 'link',
text: 'github',
url: 'https://github.com/dragonwocky/documentative/',
},
];
shorthand:
[
['getting-started.html', 'tutorial.md'],
'resources',
['github', 'https://github.com/dragonwocky/documentative/'],
];
(these methods can be mixed.)
output
build
- the output directory is created if it does not already exist.
- all assets (non-
.md) files are copied across as they are. - all markdown files included in the nav are output.
- documentative resource files are copied across:
docs.js,docs.cssand (only if no icon has been specified in the build/serve options)light-docs.pnganddark-docs.png.
note that this means you cannot have any assets with those names, as they will be overriden.
serve
a http server is created. whenever a request is received:
- if
docs.jsordocs.cssare requested, serve them from documentative's resources. - if an icon has been specified and is requested, serve it.
otherwise, the icon shall be served as
light-docs.pngordark-docs.png. - if a nav entry of type page and with an output matching the request exists, serve it.
- if the file exists in the asset list (all non-
.mdfiles), serve it. - if a file has still not been served, return a 404 error.
note that this means if you have a
.htmlfile called (e.g.)getting-started.htmland a.mdfile with its output set togetting-started.md, the parsed.mdwill override the.htmlfile.
other details
yes, some of the code blocks on this page end with unnecessary commas. my linter enforces it.
i also have an unhealthy habit of avoiding capital letters. nothing enforces this, i just do it.
the awesome logo is thanks to @nathfreder :D
if you have any questions, check my website for contact details.