frouo / next-markdown

Markdown Pages for Next.js with 0 effort, dynamic routes and your layout design
https://twitter.com/nextmarkdown
117 stars 5 forks source link

feat: allow building docs style pages #4

Closed frouo closed 2 years ago

frouo commented 2 years ago

Purpose

Allow developers to build such a page with next-markdown:

image

cf. https://chakra-ui.com/guides/integrations/with-storybook

TODO

List all files (done #5)

List every files when rendering index.md. Props should look like:

{
  ...
  html: string,
  nextmd: [...],
  files: [
    {
       ...
       html: string,
       nextmd: [..., ...],
    },
    ...
  ]
}

List previous / next files (won't do, not necessary)

This can be actually achieved with files[n-1] and files[n+1].

Table of Contents (done #8)

List markdown content headings + add anchors

Provide an example

Please provide an example in examples/.

Discussions

[x] Maybe we should rename posts attribute. It is misleading since it's not asked to be a "blog post" (as we can see, it can also achieve documentation purpose) => done, posts has been renamed to files, cf. #5

dsumer commented 2 years ago

TODO 3

Every post should get an object with the Table of Contents, which is created out of the headers inside of the post

frouo commented 2 years ago

@dsumer regarding TODO3, we should use https://github.com/JS-DevTools/rehype-toc

This plugin (in addition to https://github.com/rehypejs/rehype-slug) turns this 👇

<html>
  <body>
    <h1>Apple Pie Recipe</h1>
    <p>This is the world's best apple pie recipe...</p>

    <div>
      <h2>Filling</h2>
      <p>The filling is the best part...</p>

      <h3>Preparing the apples</h3>
      <p>Cut the apples into 1/4 inch slices...</p>

      <h3>Preparing the spice mix</h3>
      <p>In a mixing bowl, combine sugar, cinnamon...</p>
    </div>

    <div>
      <h2>Crust</h2>
      <p>How to make the perfect flaky crust...</p>

      <h3>Preparing the dough</h3>
      <p>Combine flour, sugar, salt...</p>

      <h3>The criss-cross top</h3>
      <p>Cut the top crust into 1/2 inch strips...</p>
    </div>
  </body>
</html>

Into that (it adds a nav element and id attrs) 👇

<html>
  <body>
    <nav class="toc">
      <ol class="toc-level toc-level-1">
        <li class="toc-item toc-item-h1">
          <a class="toc-link toc-link-h1" href="#apple-pie-recipe">
            Apple Pie Recipe
          </a>

          <ol class="toc-level toc-level-2">
            <li class="toc-item toc-item-h2">
              <a class="toc-link toc-link-h2" href="#filling">
                Filling
              </a>

              <ol class="toc-level toc-level-3">
                <li class="toc-item toc-item-h3">
                  <a class="toc-link toc-link-h3" href="#preparing-the-apples">
                    Preparing the apples
                  </a>
                </li>
                <li class="toc-item toc-item-h3">
                  <a class="toc-link toc-link-h3" href="#preparing-the-spice-mix">
                    Preparing the spice mix
                  </a>
                </li>
              </ol>
            </li>

            <li class="toc-item toc-item-h2">
              <a class="toc-link toc-link-h2" href="#crust">
                Crust
              </a>

              <ol class="toc-level toc-level-3">
                <li class="toc-item toc-item-h3">
                  <a class="toc-link toc-link-h3" href="#preparing-the-dough">
                    Preparing the dough
                  </a>
                </li>
                <li class="toc-item toc-item-h3">
                  <a class="toc-link toc-link-h3" href="#the-criss-cross-top">
                    The criss-cross top
                  </a>
                </li>
              </ol>
            </li>
          </ol>
        </li>
      </ol>
    </nav>

    <h1 id="apple-pie-recipe">Apple Pie Recipe</h1>
    <p>This is the world's best apple pie recipe...</p>

    <div>
      <h2 id="filling">Filling</h2>
      <p>The filling is the best part...</p>

      <h3 id="preparing-the-apples">Preparing the apples</h3>
      <p>Cut the apples into 1/4 inch slices...</p>

      <h3 id="preparing-the-spice-mix">Preparing the spice mix</h3>
      <p>In a mixing bowl, combine sugar, cinnamon...</p>
    </div>

    <div>
      <h2 id="crust">Crust</h2>
      <p>How to make the perfect flaky crust...</p>

      <h3 id="preparing-the-dough">Preparing the dough</h3>
      <p>Combine flour, sugar, salt...</p>

      <h3 id="the-criss-cross-top">The criss-cross top</h3>
      <p>Cut the top crust into 1/2 inch strips...</p>
    </div>
  </body>
</html>
dsumer commented 2 years ago

I've added a PR for the Table of Contents: https://github.com/frouo/next-markdown/pull/8

I'm not sure regarding "rehype-toc" as it adds the table of contents automatically to the html output of the markdown, which is maybe not what every user wants?

frouo commented 2 years ago

Awesome, thank you @dsumer 🙏

You are 100% right with rehype-toc as one of the main concept behind next-markdown is "build your own layout". So we want to keep the generated HTML as light as possible.

However one should be able to use rehype-toc if needed, that's why I have created https://github.com/frouo/next-markdown/issues/9.

frouo commented 2 years ago

I have been working on it last week and here is where I end with:

I think these rules will make it easy to create your own getStaticProps to fit your file structure.