npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ssg-docgen

v1.0.9

Published

Static site doc generation utility library

Downloads

22

Readme

SSG Docgen

A simple utility that parses a folder of files into a json readable format. Useful for static site generation where you want to decouple documentation from your implementation.

Usage

import SSGDocgen from 'ssg-docgen';

const parser = new SSGDocgen('/docsFolder', plugins);

// Parse specific file formats, for example markdown
parser.parseFile(['.md', '.MARKDOWN'], (data, fileInfo) => {
  // fileInfo.ext === .md
  return md.render(data);
});

// Generate all docs
parser.generate();

// Get a specific page
parser.getPage('my-page');

// Get only navigation
parser.getNavigation();

Concepts

A folder is considered a page by default, mimicking frameworks that support folder-based routing.

For files, only .json files are rendered automatically, use parser.parseFile to parse any custom formats, for example markdown. Each example below is using remarkable to parse .md files.

What if I want to document individual components on my site?

A folder with the prefix $c- is considered a component, a few things happen when parsing components;

  1. The component is bound to the page its present in and can not contain pages.
  2. Any file inside the component folder will be bound to the component.
  3. A component automatically generates anchor links to the page structure so that you can anchor it on the page.

Let's say I want to have a page containing a hero component. This is the folder structure;

page1
  $c-hero
    props.json
    description.md

will output;

{
  "navigation": [
    {
      "id": "page1",
      "label": "Page1",
      "links": null,
      "url": "/page1"
    }
  ],
  "pages": {
    "/page1": {
      "id": "page1",
      "title": "Page1",
      "components": [
        {
          "title": "Hero",
          "id": "page1/hero",
          "items": null,
          "description": "<p>content from description.md</p>",
          "props": {
            "any": "data from props.json"
          }
        }
      ],
      "anchors": [
        {
          "title": "Hero",
          "id": "page1/hero",
          "href": "#page1/hero"
        }
      ]
    }
  }
}

Nested components

Let's say you have a component that contains multiple child components. You can nest them like this:

page1
  $c-examples/
    example1/
      description.md
      props.json
    example2/
      description.md
      props.json

will output;

{
  "navigation": [
    {
      "id": "page1",
      "label": "Page1",
      "links": null,
      "url": "/page1"
    }
  ],
  "pages": {
    "/page1": {
      "id": "page1",
      "title": "Page1",
      "components": [
        {
          "title": "Examples",
          "id": "page1/examples",
          "items": [
            {
              "title": "Example1",
              "id": "page1/examples/example1",
              "description": "<p>content from description.md</p>\n",
              "props": {
                "any": "data from props.json"
              }
            },
            {
              "title": "Example2",
              "id": "page1/examples/example2",
              "description": "<p>content from description.md</p>\n",
              "props": {
                "any": "data from props.json"
              }
            }
          ]
        }
      ],
      "anchors": [
        {
          "title": "Examples",
          "id": "page1/examples",
          "items": [
            {
              "title": "Example1",
              "id": "page1/examples/example1",
              "href": "#page1/examples/example1"
            },
            {
              "title": "Example2",
              "id": "page1/examples/example2",
              "href": "#page1/examples/example2"
            }
          ]
        }
      ]
    }
  }
}

What about custom plugins?

There are times when you want to customize the output of a folder. Here we have the concept of plugins that you pass into the parse function.

A plugin is simple. It can be triggered by naming a folder with this syntax: ${myPlugin}. Then you will pass your plugin object into the parser instance as a second parameter.

const myPlugins = {
  'myPlugin': (props) => {
    // do something
    return { title: 'My plugin', data: any }
  }
}

new SSGDocgen(`/docsFolder`, myPlugins);

The function myPlugin will be called whenever an instance of ${myPlugin} is found when parsing. A plugin is expected to return an object with:

title: Used to name the output of the folder ${myPlugin}

data: Can be anything, markdown, json data, for example.

Plugin props

props will be given to you with some useful context of where this function was called and extra info:

  • props.file: current file
  • props.path: current path
  • props.page: current page
  • props.dir: current directory

Using typescript

When using typescript you can import these types to your application.

import type {
  PageContent,
  Component,
  AnchorLinks,
  NavItem,
  GetNavigationOutput,
  GenerateOutput,
  GetPageOutput,
  PluginProps,
  LibPlugin,
  LibPluginResponse,
  FileResponse,
  FileInfo
} from 'ssg-docgen/types'

Example usage;


import SSGDocgen from 'ssg-docgen';

import type {
  GenerateOutput,
  PageContent,
  NavItem,
  AnchorLinks,
  LibPlugins,
  PluginProps
} from 'ssg-docgen/types';

// Plugins
const myPlugins: LibPlugins = {
  'myPlugin': (props: PluginProps) => {
    // do something
    return {
      title: 'My plugin',
      data: "hello world"
    }
  }
}

const parser = new SSGDocgen('/docsFolder', myPlugins);
const res:GenerateOutput = parser.generate();

const pages:PageContent = res.pages;
const navigation:NavItem[] = res.navigation;
const anchors:AnchorLinks[] = pages.anchors;