├── .gitignore ├── README.md ├── api_formatting.md ├── cli.js ├── common-readme.png ├── common-readme.svg ├── package.json └── template.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | common readme 3 |

4 | 5 | ***Module consumers!*** Frustrated by each module having its own wildly 6 | unique README format? Annoyed by modules that omit critical sections like 7 | **API** or **Examples**? Stuck scrolling through API docs before you *even know 8 | what the module does*? 9 | 10 | ***Module authors!*** Tired of making up your readme format every time you 11 | write it? Do you just want consistent readmes pre-populated with your module's 12 | name, description and license without worrying about the structure every time? 13 | 14 | --- 15 | 16 | What if there was a common format for the benefit of producers and consumers? 17 | 18 | A *common readme* for node modules. 19 | 20 | This can save everybody time by adhering to 4 principles: 21 | 22 | 1. **No lock in.** No special formats or tooling; run `common-readme` once for 23 | pure vanilla markdown. 24 | 2. **No surprises.** Pull as many details out of `package.json` -- like name, 25 | description, and license -- as possible. No time wasted on configuration. 26 | 3. **Cognitive funnelling.** Start with the most general information at the top 27 | (Name, Description, Examples) and if the reader maintains interest, narrow 28 | down to specifics (API, Installation). This makes it easy for readers to 29 | "short circuit" and continue the hunt for the right module elsewhere without 30 | wasting time delving into unnecessary details. 31 | 4. **Consistency.** Your brain can scan a document much faster when it can 32 | anticipate its structure. 33 | 34 | ## Common format 35 | 36 | common-readme operates on the principle of *cognitive funneling*. 37 | 38 | > Ideally, someone who's slightly familiar with your module should be able to 39 | > refresh their memory without hitting "page down". As your reader continues 40 | > through the document, they should receive a progressively greater amount of 41 | > knowledge. -- `perlmodstyle` 42 | 43 | Here are some READMEs generated using common-readme: 44 | 45 | - [`collide-2d-aabb-aabb`](https://github.com/noffle/collide-2d-aabb-aabb) 46 | - [`goertzel`](https://github.com/noffle/goertzel) 47 | - [`twitter-kv`](https://github.com/noffle/twitter-kv) 48 | 49 | *([Submit a pull request](https://github.com/noffle/common-readme/pulls) and add 50 | yours here!)* 51 | 52 | ## Usage 53 | 54 | With [npm](https://npmjs.org/) installed, run 55 | 56 | $ npm install -g common-readme 57 | 58 | `common-readme` is a command line program. You run it when you've started a new 59 | module that has a `package.json` set up. 60 | 61 | When run, a brand new README is generated and written to your terminal. You can 62 | redirect this to `README.md` and use it as a basis for your new module. 63 | 64 | $ common-readme > README.md 65 | 66 | This brand new readme will be automatically populated with values from 67 | `package.json` such as `name`, `description`, and `license`. Stub sections will 68 | be created for everything else (Usage, API, etc), ready for you to fill in. 69 | 70 | ## Why? 71 | 72 | This isn't a crazy new idea. Other ecosystems like [Perl's 73 | CPAN](http://perldoc.perl.org/perlmodstyle.html) have been benefiting from a 74 | common readme format for years. Furthermore: 75 | 76 | 1. The node community is powered by us people and the modules we share. It's our 77 | documentation that links us together. Our README is the first thing 78 | developers see and it should be maximally effective at communicating its 79 | purpose and function. 80 | 81 | 2. There is much wisdom to be found from the many developers who have written 82 | many many modules. Common readme aims to distill that experience into a 83 | common format that stands to benefit us all; especially newer developers! 84 | 85 | 3. Writing the same boilerplate is a waste of every author's time -- we might as 86 | well generate the common pieces and let the author focus on the content. 87 | 88 | 4. Scanning through modules on npm is a part of every node developer's regular 89 | development cycle. Having a consistent format lets the brain focus on content 90 | instead of structure. 91 | 92 | ## The Art of README 93 | 94 | For even more background, wisdom, and ideas, take a look at the article that 95 | inspired common-readme: 96 | 97 | - [*Art of README*](https://github.com/noffle/art-of-readme). 98 | 99 | ## Install 100 | 101 | With [npm](https://npmjs.org/) installed, run 102 | 103 | ```shell 104 | npm install -g common-readme 105 | ``` 106 | 107 | You can now execute the `common-readme` command. 108 | 109 | ## Acknowledgments 110 | 111 | A standard readme format for the Node community isn't a new idea. Inspiration 112 | came from many conversations and unrealized efforts in the community: 113 | 114 | - 115 | - [richardlitt/standard-readme](https://github.com/RichardLitt/readme-standard) 116 | - [zwei/standard-readme](https://github.com/zcei/standard-readme) 117 | 118 | This, in addition to my own experiences evaluating hundreds of node modules and 119 | their READMEs. 120 | 121 | I was partly inspired by the audacity of the honey-badger-don't-care efforts of 122 | [standard](https://github.com/feross/standard). 123 | 124 | I also did a great deal of Perl archaeology -- it turns out the monks of the 125 | Perl community already did much of the hard work of [figuring out great 126 | READMEs](http://perldoc.perl.org/perlmodstyle.html) and the wisdom around small 127 | module development well over a decade ago. 128 | 129 | Thanks to @mafintosh, @andrewosh, and @feross for many long conversations about 130 | readmes and Node. 131 | 132 | ## See Also 133 | 134 | READMEs love [`readme`](https://www.npmjs.com/package/readme)! 135 | 136 | ## License 137 | 138 | ISC 139 | -------------------------------------------------------------------------------- /api_formatting.md: -------------------------------------------------------------------------------- 1 | # api formatting 2 | 3 | there's no one style for expressing a node api, but here are some common 4 | patterns with explanations: 5 | 6 | ## var r = repo(name, opts={}) 7 | 8 | Produces a new REPO with name `name`. Valid `opts` keys include 9 | 10 | - `db` (required) - uses the levelup instance `db` 11 | - `count` (optional) - does the thing `count` times 12 | 13 | > Shows how to create an instance of an object. `opts` is indicated to be the 14 | > empty object by default, and its required and optional parameters are 15 | > detailed. 16 | 17 | ## r.work(hard, cb(err, res)) 18 | 19 | Puts `r` to work. If `hard` is `true`, it'll even work pretty hard at it. `cb` 20 | will be called with the result of the work. 21 | 22 | > A method on the object. More importantly the indicator that it accepts a 23 | > callback function (`cb` or `callback` are both popular names). The callback's 24 | > parameters are named in `work`'s signature. 25 | 26 | ## r.pipe(stream), stream.pipe(r) 27 | 28 | `r` implements a readable stream or writeable stream, respectively. 29 | 30 | > `r` inherits `Readable` or `Writeable`, or both. 31 | 32 | ## r.on('foo', cb(bar)) 33 | 34 | `r` can raise an event named `'foo'` with the argument `bar`. 35 | 36 | > `r` is an EventEmitter, and is known to emit an event with the given name. The 37 | > callback that is ultimately called has the expected parameter `bar`. 38 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var fs = require('fs') 4 | var path = require('path') 5 | var camel = require('camelcase') 6 | var args = require('minimist')(process.argv) 7 | 8 | if (args.h || args.help) { 9 | usage() 10 | console.error() 11 | console.error('Generate a readme for your node module.') 12 | process.exit(1) 13 | } 14 | 15 | function usage () { 16 | console.error() 17 | console.log('USAGE: common-readme [-r|--repo REPO-NAME] [-l|--license LICENSE]') 18 | } 19 | 20 | var checkPkg = fs.existsSync(path.join(process.cwd(), 'package.json')) || args.l || args.license || args.r || args.repo || null 21 | 22 | if (!checkPkg) { 23 | console.error('no package.json found and no license and repo name set!') 24 | usage() 25 | process.exit(1) 26 | } 27 | 28 | var pkg = require(path.join(process.cwd(), 'package.json')) 29 | 30 | // one liner 31 | var oneliner = pkg.description || 'one-liner description of the module' 32 | 33 | // license 34 | var license = args.l || args.license || pkg.license || null 35 | if (!license) { 36 | console.error('no license set or found in package.json!') 37 | usage() 38 | process.exit(1) 39 | } 40 | 41 | // repo name 42 | var repo = args.r || args.repo || pkg.name || null 43 | if (!repo) { 44 | console.error('no repo name set or found in package.json!') 45 | usage() 46 | process.exit(1) 47 | } 48 | var repoCamel = camel(repo) 49 | 50 | // example.js 51 | var example = getExampleJs() 52 | function getExampleJs () { 53 | try { 54 | return fs.readFileSync(path.join(__dirname, 'example.js')) 55 | } catch (e) { 56 | return "var $$$rePo = require('$$$REPO')\n\nconsole.log('hello world') // => hello world" 57 | } 58 | } 59 | 60 | // read the template and regex match templated vars 61 | fs.readFileSync(path.join(__dirname, 'template.md')).toString().split('\n') 62 | .forEach(function (line) { 63 | console.log(processLine(line)) 64 | }) 65 | 66 | function processLine (line) { 67 | line = line.replace(/\$\$EXAMPLE/, example) 68 | line = line.replace(/\$\$REPO/, repo) 69 | line = line.replace(/\$\$rePo/, repoCamel) 70 | line = line.replace(/\$\$1LINER/, oneliner) 71 | line = line.replace(/\$\$ZEE_LICENSE/, license) 72 | line = line.replace(/\$\$r/, repo.charAt(0).toLowerCase()) 73 | return line 74 | } 75 | -------------------------------------------------------------------------------- /common-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackergrrl/common-readme/4379d47deb0ee6c0cc522dfc150f94c94688022b/common-readme.png -------------------------------------------------------------------------------- /common-readme.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 55 | common readme » 79 | « 91 | 92 | 93 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "common-readme", 3 | "description": "Generates a readme for your node modules.", 4 | "version": "1.1.0", 5 | "repository": { 6 | "url": "git://github.com/noffle/common-readme.git" 7 | }, 8 | "bin": { 9 | "common-readme": "cli.js" 10 | }, 11 | "dependencies": { 12 | "camelcase": "^5.0.0", 13 | "minimist": "^1.2.0" 14 | }, 15 | "license": "ISC" 16 | } 17 | -------------------------------------------------------------------------------- /template.md: -------------------------------------------------------------------------------- 1 | # $$REPO 2 | 3 | > $$1LINER 4 | 5 | background details relevant to understanding what this module does 6 | 7 | ## Usage 8 | 9 | ```javascript 10 | $$EXAMPLE 11 | ``` 12 | 13 | ## API 14 | 15 | ```js 16 | const $$rePo = require('$$REPO') 17 | ``` 18 | 19 | See [api_formatting.md](api_formatting.md) for tips. 20 | 21 | ## Installation 22 | 23 | With [npm](https://npmjs.org/): 24 | 25 | ```shell 26 | npm install $$REPO 27 | ``` 28 | 29 | With [yarn](https://yarnpkg.com/en/): 30 | 31 | ```shell 32 | yarn add $$REPO 33 | ``` 34 | 35 | ## Acknowledgments 36 | 37 | $$REPO was inspired by... 38 | 39 | ## See Also 40 | 41 | - [`noffle/common-readme`](https://github.com/noffle/common-readme) 42 | - ... 43 | 44 | ## License 45 | 46 | $$ZEE_LICENSE 47 | --------------------------------------------------------------------------------