{"id":19475508,"url":"https://github.com/artdecocode/pedantry","last_synced_at":"2026-06-09T01:33:52.241Z","repository":{"id":135405549,"uuid":"138097412","full_name":"artdecocode/pedantry","owner":"artdecocode","description":"Read a directory recursively as a stream in Node.js.","archived":false,"fork":false,"pushed_at":"2020-02-03T06:01:09.000Z","size":154,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-19T01:02:55.851Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/artdecocode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-20T23:47:05.000Z","updated_at":"2020-02-03T06:01:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"427bb36e-27d2-4141-9058-df4703f56245","html_url":"https://github.com/artdecocode/pedantry","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/artdecocode/pedantry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fpedantry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fpedantry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fpedantry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fpedantry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artdecocode","download_url":"https://codeload.github.com/artdecocode/pedantry/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fpedantry/sbom","scorecard":{"id":208907,"data":{"date":"2025-08-11","repo":{"name":"github.com/artdecocode/pedantry","commit":"15280be9ea58d3728c6910d2f0a5a4c576bf4256"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T00:21:19.453Z","repository_id":135405549,"created_at":"2025-08-17T00:21:19.453Z","updated_at":"2025-08-17T00:21:19.453Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34088013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T19:33:17.187Z","updated_at":"2026-06-09T01:33:52.220Z","avatar_url":"https://github.com/artdecocode.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pedantry\n\n[![npm version](https://badge.fury.io/js/pedantry.svg)](https://www.npmjs.com/package/pedantry)\n\n_Pedantry_ is a readable stream that puts together all files and nested directories in the given directory in sorted order (`1.md`, `2.md`, `3/1.md`, `3/1.5.md`, `10.md`, _etc_). It will also read `index.md` and `footer.md` as first and last files respectively if found.\n\n```sh\nyarn add -E pedantry\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/0.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Table Of Contents\n\n- [Table Of Contents](#table-of-contents)\n- [API](#api)\n- [class `Pedantry`](#class-pedantry)\n  * [`constructor(source: string, options?: Options): Pedantry`](#constructorsource-stringoptions-options-pedantry)\n    * [`_pedantry.Options`](#type-_pedantryoptions)\n  * [Reverse Order](#reverse-order)\n  * [Events](#events)\n  * [Object Mode](#object-mode)\n- [Ignore Hidden](#ignore-hidden)\n- [Copyright](#copyright)\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n\n## API\n\nThe main export of the program is the `Pedantry` duplex stream which should only be used as a Readable.\n\n```js\nimport Pedantry from 'pedantry'\n```\n\n\n## class `Pedantry`\n\nA _Pedantry_ instance reads files in order one-by-one and pushes the results further down the pipe.\n\n### \u003ccode\u003e\u003cins\u003econstructor\u003c/ins\u003e(\u003c/code\u003e\u003csub\u003e\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`source: string,`\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`options?: Options,`\u003cbr/\u003e\u003c/sub\u003e\u003ccode\u003e): \u003ci\u003ePedantry\u003c/i\u003e\u003c/code\u003e\n\nCreate a new readable stream. Upon creation, `Pedantry` will start reading files in the `source` directory recursively in the following order:\n\n1. the content of the `index.md` file will go first if it exists,\n1. then of all files and directories in the folder recursively in a sorted order (possibly in reverse),\n1. and the content of the `footer.md` file will go last if found.\n\n\u003cstrong\u003e\u003ca name=\"type-_pedantryoptions\"\u003e`_pedantry.Options`\u003c/a\u003e\u003c/strong\u003e: Options for Pedantry.\n\n|      Name       |       Type       |                                                                                            Description                                                                                            | Default |\n| --------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |\n| reverse         | \u003cem\u003eboolean\u003c/em\u003e | Whether to print files in reverse order, i.e., `30-file.md` before `1-file.md`.                                                                                                                   | `false` |\n| addNewLine      | \u003cem\u003eboolean\u003c/em\u003e | Add a `\\n` symbol between the content of each file.                                                                                                                                               | `false` |\n| addBlankLine    | \u003cem\u003eboolean\u003c/em\u003e | Add a blank line between the content of each file, which is equivalent to inserting `\\n\\n`.                                                                                                       | `false` |\n| includeFilename | \u003cem\u003eboolean\u003c/em\u003e | When this is set to `true`, _Pedantry_ will write data in object mode, pushing an object with `file` and `data` properties. New and blank lines will have the `file` property set to `separator`. | `false` |\n| ignoreHidden    | \u003cem\u003eboolean\u003c/em\u003e | Don't read files that start with the `.` symbol.                                                                                                                                                  | `false` |\n\n_Given the directory structure:_\n\n```m\nexample/test\n├── 1-words.md\n├── 11-to-live.md\n├── 2-believe.md\n├── 3-brick.md\n├── footer.md\n└── index.md\n```\n\n_The usage of **Pedantry** is as below:_\n\n```js\nimport Pedantry from 'pedantry'\n\nconst pedantry = new Pedantry('example/test')\npedantry.pipe(process.stdout)\n```\n```markdown\n# index.md: Welcome to Quotes\n\nThis is a collection of quotes.\n\n## 1-words.md: Mikhail Bulgakov, The Master and Margarita\n\n“You pronounced your words as if you don’t acknowledge the shadows, or the evil\neither. Would you be so kind as to give a little thought to the question of what\nyour good would be doing if evil did not exist, and how the earth would look if\nthe shadows were to disappear from it?”\n\n## 2-believe.md: Mikhail Bulgakov, The Master and Margarita\n\n“I believe you!' the artiste exclaimed finally and extinguishes his gaze. 'I do!\nThese eyes are not lying! How many times have I told you that your basic error\nconsists in underestimating the significance of the human eye. Understand that\nthe tongue can conceal the truth, but the eyes - never! A sudden question is put\nto you, you don't even flinch, in one second you get hold of yourself and know\nwhat you must say to conceal the truth, and you speak quite convincingly, and\nnot a wrinkle on your face moves, but - alas - the truth which the question\nstirs up from the bottom of your soul leaps momentarily into your eyes, and it's\nall over! They see it, and you're caught!”\n\n## 3-brick.md: Mikhail Bulgakov, The Master and Margarita\n\n“The brick is neither here nor there,' interrupted the stranger in an imposing\nfashion, 'it never merely falls on someone's head from out of nowhere. In your\ncase, I can assure you that a brick poses no threat whatsoever. You will die\nanother kind of death.\"\n\n'And you know just what that will be?' queried Berlioz with perfectly\nunderstandable irony, letting himself be drawn into a truly absurd conversation.\n'And can you tell me what that is?'\n\n'Gladly,' replied the stranger. He took Berlioz's measure as if intending to\nmake him a suit and muttered something through his teeth that sounded like 'One,\ntwo.. Mercury in the Second House... the moon has set... six-misfortune...\nevening-seven...' Then he announced loudly and joyously, 'Your head will be cut\noff!”\n\n## 11-to-live.md: Friedrich Nietzsche\n\n\u003e To live is to suffer, to survive is to find some meaning in the suffering.\n\n## footer.md: Copyright\n\n[source](https://www.goodreads.com/work/quotes/876183?page=2)\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/2.svg?sanitize=true\" width=\"15\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n### Reverse Order\n\nTo print in reverse order, the `reverse` option can be set. This feature could be useful when writing a blog, for example, as date 23 will follow 22, and in the output it will be printed first.\n\n_With a simpler directory structure:_\n\n```m\nexample/simple-test\n├── 1-file.md\n├── 100-world.md\n├── 2-test.md\n├── 21-hello.md\n├── footer.md\n└── index.md\n```\n\n_It could be printed in reverse:_\n\n```js\nimport Pedantry from 'pedantry'\n\nconst pedantry = new Pedantry('example/simple-test', {\n  reverse: true,\n})\npedantry.pipe(process.stdout)\n```\n```markdown\nindex.md\n100-world.md\n21-hello.md\n2-test.md\n1-file.md\nfooter.md\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/3.svg?sanitize=true\" width=\"15\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n### Events\n\nThe _Pedantry_ stream will emit `file` events when a file is started to be read. The content of this event is the path to the currently read file relative to the source directory.\n\n```js\nimport Pedantry from 'pedantry'\n\nconst pedantry = new Pedantry('example/simple-test')\npedantry.on('file', f =\u003e console.log(f))\n```\n```fs\nindex.md\n1-file.md\n2-test.md\n21-hello.md\n100-world.md\nfooter.md\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/4.svg?sanitize=true\" width=\"15\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n### Object Mode\n\nTo get access to the currently processed file, _Pedantry_ can be run in object mode, in which it will emit the `data` event with an object consisting of `file` and `data` properties. If blank lines are added, their will be reported as coming from the `separator` file.\n\n```js\nimport Pedantry from 'pedantry'\nimport { Transform } from 'stream'\n\nconst pedantry = new Pedantry('example/simple-test', {\n  includeFilename: true,\n  addBlankLine: true,\n})\nconst t = new Transform({\n  objectMode: true,\n  transform(object, _, next) {\n    console.log(object)\n    next()\n  },\n})\npedantry.pipe(t)\n```\n```fs\n{ file: 'example/simple-test/index.md', data: 'index.md\\n' }\n{ file: 'separator', data: '\\n\\n' }\n{ file: 'example/simple-test/1-file.md', data: '1-file.md\\n' }\n{ file: 'separator', data: '\\n\\n' }\n{ file: 'example/simple-test/2-test.md', data: '2-test.md\\n' }\n{ file: 'separator', data: '\\n\\n' }\n{ file: 'example/simple-test/21-hello.md', data: '21-hello.md\\n' }\n{ file: 'separator', data: '\\n\\n' }\n{ file: 'example/simple-test/100-world.md', data: '100-world.md\\n' }\n{ file: 'separator', data: '\\n\\n' }\n{ file: 'example/simple-test/footer.md', data: 'footer.md' }\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/5.svg?sanitize=true\" width=\"15\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Ignore Hidden\n\nTo ignore hidden files, the `{ ignore: hidden }` option can be passed to _Pedantry_. By default, this is set to false.\n\n\u003ctable\u003e\n\u003ctr\u003e\u003cth\u003e\u003ca href=\"example/hidden.js\"\u003eThe Source \u003c/a\u003e\u003c/th\u003e\u003cth\u003e\u003ca href=\"example/hidden\"\u003eThe Tree\u003c/a\u003e\u003c/th\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\n\n```js\nimport Pedantry from 'pedantry'\n\nconst HIDDEN = 'example/hidden'\nconst pedantry = new Pedantry(HIDDEN, {\n  ignoreHidden: true,\n})\npedantry.pipe(process.stdout)\n```\n\u003c/td\u003e\n\u003ctd\u003e\n\n```m\nexample/hidden\n├── .ignore\n└── 1.md\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd colspan=\"2\" align=\"center\"\u003e\u003cstrong\u003eThe Output\u003c/strong\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd colspan=\"2\"\u003e\n\n```fs\n1.md: hello world\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/6.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Copyright\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e\n      \u003ca href=\"https://www.artd.eco\"\u003e\n        \u003cimg width=\"100\" src=\"https://raw.githubusercontent.com/wrote/wrote/master/images/artdeco.png\"\n          alt=\"Art Deco\"\u003e\n      \u003c/a\u003e\n    \u003c/th\u003e\n    \u003cth\u003e© \u003ca href=\"https://www.artd.eco\"\u003eArt Deco™\u003c/a\u003e   2020\u003c/th\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/-1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartdecocode%2Fpedantry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartdecocode%2Fpedantry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartdecocode%2Fpedantry/lists"}