{"_id":"@ashnazg/mochadocs","_rev":"3-0f20996d5da54bddbff876dfec8f5e60","name":"@ashnazg/mochadocs","description":"### 1.1 * Scanning a path for test JS's (including the default path of \"test/\") now reads mjs and cjs in, not just js.","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@ashnazg/mochadocs","version":"1.0.0","author":{"url":"ashnazg.com","name":"Xander","email":"xander@ashnazg.com"},"license":"MIT","_id":"@ashnazg/mochadocs@1.0.0","maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"dist":{"shasum":"7a394d110a241d1b9ac7f8476435248bd9805135","tarball":"https://registry.npmjs.org/@ashnazg/mochadocs/-/mochadocs-1.0.0.tgz","fileCount":7,"integrity":"sha512-/Wy22mO8dC20kQ08joQZz8JaRxllAGQwRN4y+xzE8/LDPrTyqCEzjYR/C5qRzERm70LAa7On3isfkKM9yOMzug==","signatures":[{"sig":"MEUCIQDEwYQCRorwqNcbETtgZsAJne/KDilwblsd7KQ0PLelAQIgGqLM+7LtofS3uuiRLa3ricVE/OH0zvv17yu/LlrR/1Q=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":18825,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiZHjcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrqTg//fCAtKXrDA/YQ0r/a8WDuh09SF5Z8zp2+JJ96qpbmhl3S9XSo\r\nRkJUjvrdLMWA3865dulNJt9mCoFefenp6cJsIFsShWOODy+p0A3HKidyvk55\r\n38Y1AR1hpgeqRi5G4PD/kzfE1ALZAl0e29zVzR2N8IES4I999hQC8lT7wpaj\r\nVPmsOnub5sA8AIYIkWjwJOVlqwvXUwxRqUcZIZTH7qMILWEf/hb54qYRSo++\r\neYHKxxiEEdCITdOoykbT5e3unamDiKUG/OhMzac1Rk5DEn3+Pd0Dmgtv7UzM\r\nKZeBGHM/4y/yFu+WXZ8KdrocPXdaTXWpLKWq2b1cNJFprDRYsBjBrop9L6Sf\r\ns/CFODxLa0LkGgX2ZOvDdu4XrV1+m4JwQjM/NfRm+gCu8ZV8KbpNgqEcwZrp\r\nkpZIeEcEl2wKPBruYyZcTJlvvF8/sKlEguuQO8Vlta3qLLqDLb+Lw/1R1rhP\r\ncAVWCkPOknowwS9r04bcRX/xTWR0BB4qvUINuKqYy4muFlWLlJFgAi92dWpx\r\nAEZHjGk8wg2LD7LN+Vq3IovvG3locGKCl/jKap0JD31NI8ARAxQxtOvHgzle\r\n/j13vyByMlz56+V815hSiff4JFZa75i27NjBDarPF3+zmoLWnUlc3X/EYSwg\r\n5PnPLzytNK9Q8oq0yguYtntM7J0nzqIUQcc=\r\n=WhWc\r\n-----END PGP SIGNATURE-----\r\n"},"main":"lib.js","_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"description":"### Default behavior reads from `./test/` and writes `./README.md` The file you're reading was created by running: ``` const mochadocs = require('@ashnazg/mochadocs'); await mochadocs(); ``` ... and there are asserts on this page because you're reading th","directories":{},"dependencies":{"@ashnazg/utils":"^0.3.8"},"_hasShrinkwrap":false,"devDependencies":{"chai":"^4.3.6","mocha":"^9.2.2"},"_npmOperationalInternal":{"tmp":"tmp/mochadocs_1.0.0_1650751708515_0.79648129685128","host":"s3://npm-registry-packages"}},"1.0.1":{"name":"@ashnazg/mochadocs","version":"1.0.1","author":{"url":"ashnazg.com","name":"Xander","email":"xander@ashnazg.com"},"license":"MIT","_id":"@ashnazg/mochadocs@1.0.1","maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"dist":{"shasum":"14ffe6c9c81ea5c09b6a5161d02c7a4fd81292c5","tarball":"https://registry.npmjs.org/@ashnazg/mochadocs/-/mochadocs-1.0.1.tgz","fileCount":7,"integrity":"sha512-xvnh0ggQGHgZxxtE0j2yf3fqiQ4+mzpdNErqXzLndSKw+jOcEKKTOkJPL6lirZWBcuovfhG1omrjbML3yb9FZA==","signatures":[{"sig":"MEUCIQD2hok2iNJc80gLDAIwMpK9zJamkP+HAOwj254wWr7uYAIgccq2o1QRhWoNFgkSbVwfZ9hUoPEDMByJOP2sCuHFUu4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":20242,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiZfMWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmobgRAAizl7qVrOkQg/TDgiJjUCsLEy2tZlORT8ABNLtesWPHzRa1/S\r\nAYB4n2/uX6at97by62TxXB4VmD3JfbQZ3dDX7ebuhJS/hh8FSZhRvJJkbZzT\r\neGZBM8F+5R7B+AgiN67e8GJcHCOgBTqq3bKp6WZN0KAe6/c+zk5E+ytIyU63\r\nTOInemKJdiySokWFkdH1s7V/95mBqiLBWkWhnjTWNFxroLl26GpQT1+VfJZ4\r\nJWouoUZZjjAJ1Wt7129JRiY634EMhePxWALsoqv+7GM4V8ZA1smVS+NP9vn7\r\nSol6WEnPo0PF6hlItD8Q2Bs8ylVXg8lDn/TN+42uwG4GPqkCKvF84c6y604l\r\nyA1twwMVuvv9Yil7pbjJpTbjekaN/tpIVUWJFkZxqeou8ziXWvHst5hG4TSf\r\n7SlqGUpnofdiyCcCw2BzYhw0lOo8hdHsV2GuY5HulFhEdOTrGOxv+DkTYRzL\r\nQJoJgx/GjsGQFiupj5ChDeIOnC9Hy8d2jQOC5VdMKSTtmIzO2ucKCrKVpPJJ\r\nZ2qi0sCJV2iePVhHcQZYOU3CPU8S50T6/rY1jSeuBPNvFKQFpUZFMjubmC5I\r\n/hhyQOL+DBElJGe6qioRBsokfeZoUkJnc27/z6PrpLXn964NFz5wSURiO2Vh\r\n3XL7xUjaTaRtm3H01MtuBC7K/R456h630LU=\r\n=ZOkz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"lib.js","_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"description":"### Default behavior reads from `./test/` and writes `./README.md` The file you're reading was created by running: ```js const mochadocs = require('@ashnazg/mochadocs'); await mochadocs(); ``` ... and there are asserts on this page because you're reading ","directories":{},"dependencies":{"@ashnazg/utils":"^0.3.8"},"_hasShrinkwrap":false,"devDependencies":{"chai":"^4.3.6","mocha":"^9.2.2"},"_npmOperationalInternal":{"tmp":"tmp/mochadocs_1.0.1_1650848534716_0.14386366336401202","host":"s3://npm-registry-packages"}},"1.0.2":{"name":"@ashnazg/mochadocs","version":"1.0.2","author":{"url":"ashnazg.com","name":"Xander","email":"xander@ashnazg.com"},"license":"MIT","_id":"@ashnazg/mochadocs@1.0.2","maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"dist":{"shasum":"ce6b05bf0dd66afa6b8ce5cc478bfebd209a8f64","tarball":"https://registry.npmjs.org/@ashnazg/mochadocs/-/mochadocs-1.0.2.tgz","fileCount":10,"integrity":"sha512-GxF/MUVCImmyBz6gx2JMni9phkhekvSMMcb0Kh2BOlQfsJ0BQaT83givHnoC3QRODPAbeZ35G88fZNQcTiLR6w==","signatures":[{"sig":"MEUCIDWpqBmFx3sTcbSWR3meMa+OUc03tZEYbImwmww3R2YhAiEAyIlx2fBPNURt6Tc/M4E+x7XekHi1/qx+BoGZXJtXB2Y=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":21036,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi8HUyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpYww/+IbIXxKTu/DYMzF2i12s5bvmsFheUmIah2E37bIHojA3FrsTR\r\n5ZLeyircJ9zcsPAwwbHUYNcOBBWUQBoMOXs3hROKqg33AMwYsH5fqORlkTzp\r\ncjTij0Y879TGjaJvBWWHblszZusoWw5qupZtl81VtIKG/9hDYXmUJ6ZkI4Px\r\nXqWVLq0kpuOu87QX0FSvbZSbsEHGzZrQ7rxtBL7Pmhccr7J1lX2Sl47Aezxr\r\nC3C6ppxxD+C6/YJ339pnGOpsvb0GM/twOGEMHJkaPqKyPV/EnjuUmTLLc+dx\r\nJwEgIvUpsXxELMtaavTfEO3Xwq2N41qJ45vX/m6UI9NY6Oc5ftWiAQMAmhsf\r\nEyQE9pJBPAsv77TTEj7bN0ks5pyiHORu2VpSesjaPqph5F5m5X+hnyZy13wG\r\nGg8xhGIH1Ydxdtn4eaAhNAZ/yQv7+6MxKmfVOYvBjWuAvLZQLxxmJ6ITL1co\r\nR1W/L7quWxq6rzdleW1yAIdSddTbV+dc5OmdSJ4x+fV/vm8ghGXDM/AzgvFn\r\nQiqmT3TMdVPCPWo6YjWOj9nzFXRplPkdoTgQuk3zQ93Zaxq6HFykg/iQdt81\r\n2A+pGpDvGmZKuVzbtymZfNghraeP8s+BZTbxVIBCSrSu0Qns/uD6YPlp5o90\r\n7EwHOxTT6CtSu9i+sSWZuIcIesyVHKEGspY=\r\n=pSsu\r\n-----END PGP SIGNATURE-----\r\n"},"main":"lib.js","_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"description":"### Default behavior reads from `./test/` and writes `./README.md` The file you're reading was created by running: ```js const mochadocs = require('@ashnazg/mochadocs'); await mochadocs(); ``` ... and there are asserts on this page because you're reading ","directories":{},"dependencies":{"@ashnazg/utils":"^0.3.10"},"_hasShrinkwrap":false,"devDependencies":{"chai":"^4.3.6","mocha":"^9.2.2"},"_npmOperationalInternal":{"tmp":"tmp/mochadocs_1.0.2_1659925809959_0.9350883461567336","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"@ashnazg/mochadocs","version":"1.1.0","main":"lib.js","author":{"name":"Xander","email":"xander@ashnazg.com","url":"ashnazg.com"},"license":"MIT","devDependencies":{},"dependencies":{"@ashnazg/utils":"^0.5.0"},"description":"### 1.1 * Scanning a path for test JS's (including the default path of \"test/\") now reads mjs and cjs in, not just js.","_id":"@ashnazg/mochadocs@1.1.0","dist":{"shasum":"4632338551388aa1ca6ada7cc3a5df387ded0ab6","integrity":"sha512-EU0ZIKR9YUFXwDUvSHFo3x/H/JUipUMnG8gCUwMQGLStKxNXJmeBQ7+vwSScPee7C0pmYSQOoezLwtPfhEH1+Q==","tarball":"https://registry.npmjs.org/@ashnazg/mochadocs/-/mochadocs-1.1.0.tgz","fileCount":10,"unpackedSize":21476,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB55J+VPDH9wgYhiR+1AMo3r9DPBczAGVA2VZJVb78SBAiEAqqAYrjldP8oJb5J/fcJoPQGMQhDeio/9AXW2G1EqcDU="}]},"_npmUser":{"name":"xander","email":"xander@ashnazg.com"},"directories":{},"maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/mochadocs_1.1.0_1720050741102_0.2896679171065131"},"_hasShrinkwrap":false}},"time":{"created":"2022-04-23T22:08:28.458Z","modified":"2024-07-03T23:52:21.473Z","1.0.0":"2022-04-23T22:08:28.652Z","1.0.1":"2022-04-25T01:02:14.832Z","1.0.2":"2022-08-08T02:30:10.126Z","1.1.0":"2024-07-03T23:52:21.289Z"},"maintainers":[{"name":"xander","email":"xander@ashnazg.com"}],"author":{"name":"Xander","email":"xander@ashnazg.com","url":"ashnazg.com"},"license":"MIT","readme":"**Purpose**\n\nI really wanted something like sphinx or doxygen but with the least possible syntax and the most DRY I could think of.\n\nPrinciples:\n1. Readable code is the best documentation.\n2. Readable tests is the 2nd best documentation.\n3. While real design docs shouldn't be crammed into this format, the unit tests file be a significant (hyperlinked) participant reduces how much pure prose has to be written.\n\n## Releases\n### 1.1\n* Scanning a path for test JS's (including the default path of \"test/\") now reads mjs and cjs in, not just js.\n\n## Reads Mocha test files and emits a README.md\n\n### Default behavior\nreads from `./test/` and writes `./README.md`\nThe file you're reading was created by running:\n```js\nconst mochadocs = require('@ashnazg/mochadocs');\nawait mochadocs();\n```\n... and there are asserts on this page because you're reading the unit tests.\n### what's emitted\n1. Lines that begin with `///` are emitted as markdown.\n1. `describe(...)` is parsed to make h2's\n1. `it(...)` is parsed to make h3's\n1. Lines of code or vanilla comments are also emitted, but wrapped in a pre-block.\n\n### Supports Transclusion\nA line that is exactly `///{{filename}}` will try to cat that filename in.\n\n**big Nota Bene:** This is relative to the PWD of the process, NOT relative to the file the transclusion is present in.\n\nThe Release section on this page was transcluded from another file by saying:\n`///{{CHANGELOG.md}}`\n\n## Options\n\n### Defaults\nif no params given, defaults to:\n```js\nawait mochadocs({path: 'test'});\n```\nif you don't need any other options, you can pass it just the path string:\n```js\nawait mochadocs('test');\n```\nthe full config format is:\n```js\nawait mochadocs({\n\tpath: 'test',\n\tto: 'README.md',\n\tlibname: '@ashnazg/mochadocs',\n\tglossary: { // for auto-linking frequently used terms\n\t\tacronym1: 'path1',\n\t},\n\tindent: '\\t\\t'\n});\n```\n\n### Support for space-indented files\nVisible code blocks are defined as non-`/// ` lines that start with `conf.indent` and are between the opening line of the current `it(...)`\nand the it-closer, which is the first line of code with less indentation thatn conf.indent.\n\nso for a 2-space file like:\n```\ndescribe('group', function() {\n  it('thing', function() {\n    visible_code();\n  });\n  function invisibleHelper() {\n    invisible_code();\n  };\n});\n```\nYou'd use:\n```\nawait mochadocs({\n  indent: '    ' // four spaces\n});\n```\n\nWhen the indent drops below the conf.indent, code blocks are not emitted til the next `it(` -- this is so the invisibleHelper's contents don't pollute the unit test's\ncode printout.\n\n### Explicit output\nyou can write the output to a specific place:\n```js\nawait mochadocs({to: 'different.md'});\n{\n\tconst lines = (await fs.promises.readFile('different.md', 'utf8')).split('\\n');\n\tassert(lines[length_of_preamble] === '## Reads Mocha test files and emits a README.md');\n}\n```\nor pass null as the destination and it'll return the markdown file as a list of lines:\n```js\n{\n\tconst lines = await mochadocs({to: null});\n\tassert(lines[length_of_preamble] === '## Reads Mocha test files and emits a README.md');\n}\n```\n\n### Explicit input, file\npath can be a filename:\n```js\nconst lines = await mochadocs({path: 'test/basics.js', to: null});\nassert(lines[length_of_preamble] === '## Reads Mocha test files and emits a README.md');\n```\n\n### Explicit input, dir\n... or a directory, in which it'll read all `*.js`, including subfolders, and process them after sorting them by 'path/filename'.\n```js\nconst lines = await mochadocs({path: 'test', to: null});\nassert(lines[length_of_preamble] === '## Reads Mocha test files and emits a README.md');\n```\n\n### Replaces require('..')\nsince in a library's unit tests, `require('..')` is useful, but not helpful documentation,\nThis is converted to `require('LIBNAME')`.\n```js\nconst lines = await mochadocs({path: 'test', to: null}); // reading the output of section \"default\"\nconst hits = lines.filter(line => line === \"const mochadocs = require('@ashnazg/mochadocs');\");\nassert(hits.length === 1);\n```\n\n### Configuring require('..') replacement\nBy default, mochadocs assumes that `./package.json` is available and will use that to know your lib's name.\nif that's not a useful guess (wrong path or wrong name) you can pass in a library name of your choosing as a third param:\n```js\nconst lines = await mochadocs({path: 'test', to: null, libname: 'custom_lib_name'});\nconst hits = lines.filter(line => line === \"const mochadocs = require('custom_lib_name');\");\nassert(hits.length === 1);\n```\n\n### Automatic Glossary\nTo allow good linkage to other relevant topics without repetitive writing, you can pass in a glossary map and if that key is found in the non-code blocks, it'll be\nemitted as a link:\n```js\nlines = await mochadocs({\n\tto: null,\n\tglossary: {\n\t\tGLOSSARY: 'https://en.wikipedia.org/wiki/Glossary'\n\t}\n});\n```\n\n## Glossary Rules\n\n### Only links exact words\nGiven the above config, the word \"[GLOSSARY](https://en.wikipedia.org/wiki/Glossary)\" is now a link.\n```js\n// search term without creating a false positive:\n{\n\tconst key = `[GLOS` + `SARY](https://en.wikipedia.org/wiki/Glossary)`;\n\tconst hits = lines.filter(line => line.includes(key));\n\tassert(hits.length === 1, `${hits.length} hits`);\n}\n```\n... but GLOSSARYFOO is not, because the replacer respects word boundaries.\n```js\n{\n\tconst key = `GLOS` + `SARYFOO`;\n\tconst hits = lines.filter(line => line.includes(key));\n\tassert(hits.length === 1, `${hits.length} hits`);\n}\n```\n\n### Longer glossary terms take precedence\n```js\nawait mochadocs({\n\tglossary: {\n\t\tGLOSSARY: 'https://en.wikipedia.org/wiki/Glossary',\n\t\tSHORT_NAME: '#glossary-rules',\n\t\tSHORT_NAME_IN_LONGER_NAME: '#longer-glossary-terms-take-precedence'\n\t}\n});\n```\n[SHORT_NAME_IN_LONGER_NAME](#longer-glossary-terms-take-precedence) should be a clean link, and its internals should not be affected by the [SHORT_NAME](#glossary-rules) term, as replacement is not allowed to go into recursive\nexpansion.\n```js\nconst lines = (await fs.promises.readFile('README.md', 'utf8')).split('\\n');\nconst key = `[SHORT_NAM` + `E_IN_LONGER_NAME](#longer-glossary-terms-take-precedence) should be a clean link, and its internals should not be affected by the [SHORT_NAME](#glossary-rules) term`;\nconst hits = lines.filter(line => line.includes(key));\nassert(hits.length === 1, `${hits.length} hits`);\n```\n\n### Existing links are unaffected\nthis predefined link [SHORT_NAME](#existing-links-are-unaffected) is not further processed.\n```js\nconst lines = (await fs.promises.readFile('README.md', 'utf8')).split('\\n');\n// here's the unwanted form:\nconst key = `[[SHORT` + `_NAME](test1)](#existing-links-are-unaffected)`;\nconst hits = lines.filter(line => line.includes(key));\nassert(hits.length === 0, `${hits.length} hits`);\n```\n\n## Release 1.0.2\n\n### fixed a bug where a really short input file leaves the code pre unclosed\n```js\nconst lines = await mochadocs({path: 'samples/trailing-pre-missing.js', to: null});\nassert(lines[lines.length-1] === '```', 'simple did not close pre');\n```\n\n## Release 1.0.1\n1. Suppressed codeblocks that aren't inside an `it(...)`\n\n## Release 1.0\n1. Wrote the thing\n","readmeFilename":"README.md"}