{"id":22650012,"url":"https://github.com/pauliorandall/p24","last_synced_at":"2026-02-27T09:35:42.005Z","repository":{"id":236771371,"uuid":"793122617","full_name":"PaulioRandall/p24","owner":"PaulioRandall","description":"Simple tool for documenting Svelte components.","archived":false,"fork":false,"pushed_at":"2024-07-02T09:10:39.000Z","size":238,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"trunk","last_synced_at":"2025-11-17T09:23:57.047Z","etag":null,"topics":["documentation","plunder","svelte"],"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/PaulioRandall.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2024-04-28T13:46:43.000Z","updated_at":"2024-07-02T09:10:28.000Z","dependencies_parsed_at":"2024-05-01T22:55:15.301Z","dependency_job_id":"97adf63d-b6ba-49d5-a702-940175792cb1","html_url":"https://github.com/PaulioRandall/p24","commit_stats":null,"previous_names":["pauliorandall/p24"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/PaulioRandall/p24","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp24","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp24/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp24/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp24/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PaulioRandall","download_url":"https://codeload.github.com/PaulioRandall/p24/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulioRandall%2Fp24/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29889456,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T08:34:21.514Z","status":"ssl_error","status_checked_at":"2026-02-27T08:32:38.035Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["documentation","plunder","svelte"],"created_at":"2024-12-09T08:30:00.773Z","updated_at":"2026-02-27T09:35:41.979Z","avatar_url":"https://github.com/PaulioRandall.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Made to be Plundered](https://img.shields.io/badge/Made%20to%20be%20Plundered-royalblue)\n[![Latest version](https://img.shields.io/github/v/release/PaulioRandall/p24)](https://github.com/PaulioRandall/p24/releases)\n[![Release date](https://img.shields.io/github/release-date/PaulioRandall/p24)](https://github.com/PaulioRandall/p24/releases)\n\n# P24\n\nSimple tool for documenting Svelte components.\n\n## Made to be Plundered\n\nFork, pillage, and plunder! Do whatever as long as you adhere to the project's permissive MIT license.\n\n## Functions\n\n### `parse(options = {})`\n\nGiven the component:\n\n```html\n\u003c!--\n  ArticlePreview.svelte\n\n  This comment is not parsed by P24. If a comment\n  doesn't start with '@' then it's just a normal\n  comment.\n  \n  Name is inferred from the file name but may be\n  specified as below.\n--\u003e\n\n\u003c!--@component ArticleListItem\n  To be slotted into either an `ArticleList` or\n  `ArticleGrid` component. It presents summary\n  information about the article and a preview image.\n  clicking the component will take the user to the\n  full article.\n--\u003e\n\n\u003cscript context=\"module\"\u003e\n  import { base } from '$app/paths'\n\n  //@prop toFullPath\n  // Resolves a relative URL path to a full URL path\n  // by prepending the application base path.\n  // @module\n  // @const\n  export const toFullPath = (relPath) =\u003e {\n    return `${base}/${relPath}`\n  }\n\u003c/script\u003e\n\n\u003cscript\u003e\n  import { setContext } from 'svelte'\n\n  //@prop title\n  // Title of the article.\n  export let title\n\n  //@prop author\n  // Name of the person or people who wrote the article.\n  export let author\n\n  //@prop link\n  // URL to the full article.\n  export let link\n\n  //@prop published\n  // Date the article was published or falsy value if\n  // not yet published.\n  // @default null \n  export let published = null\n\n  //@prop image\n  // URL of the preview image or falsy value to use\n  // the stock image. You may used the named slot\n  // 'image' if custom HTML is needed.\n  // @default null\n  export let image = null\n\n  /*@ctx article-list-item\n    All details about the article including whether\n    slotted image and summary were provided.\n  */\n  setContext('article-list-item', {\n    title,\n    author,\n    link,\n    isPublished: !!published,\n    published,\n    image,\n    hasImageSlot: $$slots.image,\n    hasSummary: $$slots.default,\n  })\n\u003c/script\u003e\n\n\u003carticle\u003e\n  \u003ch2\u003e{title}\u003c/h2\u003e\n\n  {#if $$slots.image}\n    \u003c!--@slot image\n      Alternative to using the 'image' property if\n      custom HTML is needed to present the article\n      preview thumbnail.\n    --\u003e\n    \u003cslot name=\"image\" /\u003e\n  {:else if image}\n    \u003cimg src={image} /\u003e\n  {:else}\n    \u003cimg src=\"/images/stock-article-preview-image.jpg\" /\u003e\n  {/if}\n\n  \u003c!--@slot\n    Short description of the article.\n  --\u003e\n  \u003cslot /\u003e\n\u003c/article\u003e\n```\n\nWhen parsed with:\n\n```js\nimport p24 from 'p24'\n\nconst fileDocs = p24.parse()\n```\n\nThen `fileDocs` will be something similar to:\n\n```js\n[\n  {\n    name: \"ArticlePreview.svelte\",\n    description: \n    relPath: \"./src/lib/ArticlePreview.svelte\",\n    absPath: \"/home/esmerelda/github/my-project/src/lib/ArticlePreview.svelte\",\n    nodes: {\n      name: \"ArticleListItem\",\n      descriptions: `To be slotted into either an \\`ArticleList\\` or \\`ArticleGrid\\` component. It\npresents summary information about the article and a preview image.\nclicking the component will take the user to the full article.`,\n      module: {\n        const: {\n          toFullPath: `Resolves a relative URL path to a full URL path by prepending the\napplication root path.`\n        }\n      },\n      props: {\n        let: {\n          title: \"Title of the article.\",\n          author: \"Name of the person or people who wrote the article.\",\n          link: \"URL to the full article.\",\n          published: \"Date the article was published or falsy value if not yet published.\"\n          image: `URL of the preview image or falsy value to use the stock image.\nYou may used the named slot 'image' if custom HTML is needed.`\n        }\n      },\n      context: {\n        'article-list-item': `All details about the article including whether slotted image and summary\nwere provided.`\n      },\n      slots: {\n        image: `Alternative to using the 'image' property if custom HTML is needed to\npresent the article preview image.`,\n        default: \"Short description of the article.\"\n      },\n    }\n  }\n]\n```\n\n**Options**\n\nDefaults noted as field values. For information on glob and glob options see [NPM _glob_ package](https://www.npmjs.com/package/glob) ([Github](https://github.com/isaacs/node-glob)).\n\n```js\nimport p24 from 'p24'\n\np24.parse({\n  // Custom prefix for nodes.\n  prefix: \"@\",\n\n  // For SvelteKit packaged libraries you would use\n  // \"dist/*.svelte\" or some variation of it.\n  glob: \"**/*.svelte\",\n  globOptions: {}\n})\n```\n\n### `renderReadme(options = {})`\n\nParses the documentation then compiles a README from a template with the documentation.\n\nBy default, a template README file called `README.template.md` is read, placeholder text `{{PLACEHOLDER}}` is swapped out for the rendered documentation, before finally writing the whole thing to `README.md`.\n\nExample output for a single component:\n\n~~~markdown\n### `\u003cForm\u003e`\n\nPrimary component in which fields are slotted into.\n$restProps are passed to the form element (outer component element).\n\n```svelte\n\u003cscript context=\"module\"\u003e\n  // Store containing fields referenced by their input names.\n  export let fields = writable({})\n\n  // Store containing values referenced by their input names.\n  export let values = writable({})\n\n  // Store containing error messages referenced by their input names.\n  // An empty string represents either no error or unvalidated.\n  export let errors = writable({})\n\n  // Store containing the passed form level properties.\n  // \n  // $form = {\n  //    id,\n  //    validate,\n  //    submit,\n  // }\n  export let form = writable({})\n\u003c/script\u003e\n```\n\n```svelte\n\u003cscript\u003e\n  // Element id of the form.\n  export let id = /* = Randomly assigned ID. */\n\n  // Function for validating all fields. It accepts a field name to value\n  // object and must return a field name to errors object.\n  export let validate = null\n\n  // Function for submitting the form. It accepts a field name to value\n  // object.\n  export let submit = null\n\n  // See fields property.\n  setContext(\"p17-fields\", ...)\n\n  // See values property.\n  setContext(\"p17-values\", ...)\n\n  // See errors property.\n  setContext(\"p17-errors\", ...)\n\n  // See form property.\n  setContext(\"p17-form\", ...)\n\u003c/script\u003e\n\n\u003c!-- Form fields, buttons, and anything else you fancy. --\u003e\n\u003cslot /\u003e\n```\n\n```svelte\n\u003cForm\n  id={/* = Randomly assigned ID. */}\n  validate={null}\n  submit={null}\n\u003e\n  \u003cdiv /\u003e\n\u003c/Form\u003e\n```\n~~~\n\n**Options**\n\nDefaults noted as field values. \n\nFor information on glob and glob options see [NPM _glob_ package](https://www.npmjs.com/package/glob) ([Github](https://github.com/isaacs/node-glob)).\n\n```js\nimport p24 from 'p24'\n\np24.parse({\n  // Custom prefix for nodes.\n  prefix: \"@\",\n\n  // For SvelteKit packaged libraries you would use\n  // \"dist/*.svelte\" or some variation of it.\n  glob: \"**/*.svelte\",\n  globOptions: {}\n\n  // The name of the README template file.\n  template: './README.template.md',\n\n  // The output file name.\n  output: './README.md',\n\n  // The placeholder text in the template to swap\n  // for the parsed and rendered documentation. \n  placeholder: '{{PLACEHOLDER}}',\n})\n```\n\n**CLI**\n\nThis functionality is also available in CLI form allowing commands such as:\n\n```bash\nnpx p24\n```\n\nAnd `package.json` scripts:\n\n```json\n{\n  \"scripts\": {\n    \"docs\": \"p24\"\n  }\n}\n```\n\nWith most arguments available:\n\n```bash\nnpx p24 \\\n  --prefix \"@\" \\\n  --glob \"**/*.svelte\" \\\n  --template \"README.template.md\" \\\n  --output \"README.md\" \\\n  --placeholder \"{{PLACEHOLDER}}\"\n```\n\nOr:\n\n```bash\nnpx p24 \\\n  -p \"@\" \\\n  -g \"**/*.svelte\" \\\n  -t \"README.template.md\" \\\n  -o \"README.md\" \\\n  -s \"{{PLACEHOLDER}}\"\n```\n\n## Back Story\n\nI simply wanted to document a component's API within itself and regenerate that documentation in a form I please, particularly within a README. To clarify, I want to document the **interface** (API) to the component by documenting its single implementation. Ths includes details such as its name, description, module and instance properties, slots, set context, and defaults where applicable.\n\nA few documentation tools come close but none completely satisfy my need for simplicity, readability, flexibility, and ability to document all mentioned aspects of the API. Furthermore, existing tools traded-off too much flexibility for conciseness. So I set about creating **P24**. In the process I was able to separate the concern of parsing annotated comments into [**P23**](https://github.com/PaulioRandall/p23).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpauliorandall%2Fp24","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpauliorandall%2Fp24","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpauliorandall%2Fp24/lists"}