Tidy up styling, add basic ToC component.

This commit is contained in:
Joshua Bemenderfer 2023-02-14 16:47:38 -05:00
parent 54ad373744
commit 3b464c523e
13 changed files with 305 additions and 216 deletions

View File

@ -9,10 +9,10 @@
<meta name="description" content="{{ description | join(' ') }}"/> <meta name="description" content="{{ description | join(' ') }}"/>
{% eleventyGoogleFonts 'https://fonts.googleapis.com/css2?family=Fredoka:wght@300;400;500&display=swap' %} {% eleventyGoogleFonts 'https://fonts.googleapis.com/css2?family=Fredoka:wght@300;400;500&display=swap' %}
</head> </head>
<body class="text-base"> <body class="text-base pt-16">
{{ Node('Navbar', {}, page) }} {{ Node('Navbar', {}, { headings: headings, url: page.url }) }}
{% for child in children %} {% for child in children %}
{{ Node(child.type, child, page) }} {{ Node(child.type, child, { headings: headings, url: page.url }) }}
{% endfor %} {% endfor %}
<script type="module" src="/main.js"></script> <script type="module" src="/main.js"></script>
</body> </body>

View File

@ -1,11 +1,11 @@
{% macro render(node) %} {% macro render(node) %}
{% if node.variant == 'small' %} {% if node.variant == 'small' %}
<div class="flex gap-2 items-center"> <div class="flex gap-2 items-center {{node.class}}">
<img src="/logo.png" class="w-8 h-8" alt=""/> <img src="/logo.png" class="w-8 h-8" alt=""/>
<span class="text-3xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600">Terrace</span> <span class="text-3xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600">Terrace</span>
</div> </div>
{% else %} {% else %}
<div class="flex gap-4 items-center"> <div class="flex gap-4 items-center {{node.class}}">
<img src="/logo.png" class="w-8 h-8 md:w-16 md:h-16" alt=""/> <img src="/logo.png" class="w-8 h-8 md:w-16 md:h-16" alt=""/>
<h1 class="text-xl md:text-5xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600">Terrace</h1> <h1 class="text-xl md:text-5xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600">Terrace</h1>
</div> </div>

View File

@ -1,13 +1,11 @@
{% from "./Node.njk" import Node %} {% from "./Node.njk" import Node %}
{{ page | dump }}
{% macro navlink(href, text, active) %} {% macro navlink(href, text, active) %}
<a href="{{ href }}" class="flex items-center hover:text-primary-400 {{ 'text-primary-400' if href in active }}">{{ text }}</a> <a href="{{ href }}" class="flex items-center hover:text-primary-400 {{ 'text-primary-400' if href in active }}">{{ text }}</a>
{% endmacro %} {% endmacro %}
{% macro render(node, page) %} {% macro render(node, ctx) %}
<nav class="fixed left-0 right-0 top-0 lg:relative bg-neutral-800 text-neutral-50 h-20 flex items-center z-10"> <nav class="fixed left-0 right-0 top-0 lg:absolute bg-neutral-800 text-neutral-50 h-20 flex items-center z-10">
<div class="container mx-auto px-8 flex items-center space-between"> <div class="container mx-auto px-8 flex items-center space-between">
<a id="nav" class="peer" href="#nav" aria-hidden="true" tabindex="-1"></a> <a id="nav" class="peer" href="#nav" aria-hidden="true" tabindex="-1"></a>
@ -29,10 +27,10 @@
lg:pointer-events-auto lg:pointer-events-auto
lg:relative lg:top-0 lg:px-0 lg:flex-row lg:flex-1 lg:h-20 lg:bg-neutral-800 lg:text-white lg:relative lg:top-0 lg:px-0 lg:flex-row lg:flex-1 lg:h-20 lg:bg-neutral-800 lg:text-white
"> ">
{{ navlink("/docs/", "Docs", page.url) }} {{ navlink("/docs/", "Docs", ctx.url) }}
{{ navlink("/examples/", "Examples", page.url) }} {{ navlink("/examples/", "Examples", ctx.url) }}
{{ navlink("/about/", "About", page.url) }} {{ navlink("/about/", "About", ctx.url) }}
{{ navlink("/contribute/", "Contribute", page.url) }} {{ navlink("/contribute/", "Contribute", ctx.url) }}
<a href="/docs/" class="flex items-center hover:text-primary-400">Contribute</a> <a href="/docs/" class="flex items-center hover:text-primary-400">Contribute</a>
<div class="-order-1 lg:order-2 flex items-center">{{ Node('SearchBox', { class: 'w-full lg:w-72' }) }}</div> <div class="-order-1 lg:order-2 flex items-center">{{ Node('SearchBox', { class: 'w-full lg:w-72' }) }}</div>
<a href="https://git.thederf.com/thederf/Terrace" target="_blank" class="flex items-center hover:text-primary-400 order-3"> <a href="https://git.thederf.com/thederf/Terrace" target="_blank" class="flex items-center hover:text-primary-400 order-3">

View File

@ -1,4 +1,4 @@
{% macro Node(name, params, page) %} {% macro Node(name, params, ctx) %}
{% from "./" + name + ".njk" import render %} {% from "./" + name + ".njk" import render %}
{{ render(params, page) }} {{ render(params, ctx) }}
{% endmacro %} {% endmacro %}

View File

@ -6,14 +6,14 @@
} }
%} %}
{% macro render(node, page) %} {% macro render(node, ctx) %}
<svg class="w-full -mt-[55px] {{ 'text-neutral-50' if node.variant == 'light' else 'text-neutral-800' }}" viewBox="0 0 1920 55"> <svg class="w-full -mt-[55px] {{ 'text-neutral-50' if node.variant == 'light' else 'text-neutral-800' }}" viewBox="0 0 1920 55">
<path d="M0 55H1920V6.99994C1811 55 1150 55 403.5 6.99994C141.541 -9.84407 0 6.99996 0 55Z" fill="currentColor"/> <path d="M0 55H1920V6.99994C1811 55 1150 55 403.5 6.99994C141.541 -9.84407 0 6.99996 0 55Z" fill="currentColor"/>
</svg> </svg>
<section class="group/{{node.variant}} {{ variants[node.variant] }}"> <section class="group/{{node.variant}} {{ variants[node.variant] }}">
<div class="{{ node.class }} container mx-auto px-8 pt-16 md:pt-8 pb-32"> <div class="{{ node.class }} container mx-auto px-8 pt-16 pb-48">
{% for child in node.children %} {% for child in node.children %}
{{ Node(child.type, child, page) }} {{ Node(child.type, child, ctx) }}
{% endfor %} {% endfor %}
</div> </div>
</section> </section>

View File

@ -0,0 +1,19 @@
{% macro renderHeadings(headings) %}
<ul class="pl-4">
{% for heading in headings %}
<li class="my-4">
<a href="#{{ heading.slug }}" class="hover:text-primary-400">{{ heading.text }}</a>
{% if heading.children %}
{{ renderHeadings(heading.children)}}
{% endif %}
</li>
{% endfor %}
</ul>
{% endmacro %}
{% macro render(node, ctx) %}
<div class="my-4 font-medium text-2xl">Table of Contents</div>
<div class="-ml-3">
{{ renderHeadings(ctx.headings) }}
</div>
{% endmacro %}

View File

@ -5,229 +5,250 @@ description
Terrace gets out of your way to let you just write Terrace gets out of your way to let you just write
Section dark Section dark
class pt-40 md:pt-32 max-w-prose class flex flex-col md:flex-row gap-16
Heading 1 About Terrace Block
class w-full lg:w-1/3
Markdown TableOfContents
Terrace is a tiny system for storing data in human-friendly text files.
It allows you to mix all sorts of text and data formats together in an intuitive way without getting caught up in syntax pomp and ceremony. Block
class max-w-prose
CodeBlock terrace Heading 1 About Terrace
title An Essay on Rockets
date 2022-02-22
by John Doe
heading The ideal rocket equation Markdown
Terrace is a tiny system for storing data in human-friendly text files.
equation LaTeX It allows you to mix all sorts of text and data formats together in an intuitive way without getting caught up in syntax pomp and ceremony.
\Delta v=v_{\text{e}}\ln {\frac {m_{0}}{m_{f}}}=I_{\text{sp}}g_{0}\ln {\frac {m_{0}}{m_{f}}}
markdown CodeBlock terrace
A fundamental equation in astrophysics, the *ideal rocket equation* describes the total potential velocity of an idealized vehicle propelled by expelling some of its own mass. title An Essay on Rockets
date 2022-02-22
by John Doe
... heading The ideal rocket equation
Markdown equation LaTeX
class prose-invert \Delta v=v_{\text{e}}\ln {\frac {m_{0}}{m_{f}}}=I_{\text{sp}}g_{0}\ln {\frac {m_{0}}{m_{f}}}
You can use Terrace to write documents, web pages, configuration files, data storage, or whatever else you come up with!
[This page](https://git.thederf.com/thederf/Terrace/src/branch/main/docs/src/about.tce) is written using Terrace! markdown
A fundamental equation in astrophysics, the *ideal rocket equation* describes the total potential velocity of an idealized vehicle propelled by expelling some of its own mass.
...
Markdown
class prose-invert
You can use Terrace to write documents, web pages, configuration files, data storage, or whatever else you come up with!
[This page](https://git.thederf.com/thederf/Terrace/src/branch/main/docs/src/about.tce) is written using Terrace!
Section light Section light
class max-w-prose class flex flex-col md:flex-row gap-16
Heading 2 Background
Markdown Block
Terrace was originally envisioned out of frustration at the massive usability gulf for embedding custom blocks in simple, human-friendly markup formats such as [Markdown](), and capable but complex block-based systems such as [Project Gutenberg](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/writing-your-first-block-type/) and [Editor.js](https://editorjs.io/saving-data/). class w-1/3
Heading 3 The Complexity Problem Block
class mt-8 mb-4 class max-w-prose
Markdown Heading 2 Background
**A simple markdown document:**
CodeBlock markdown Markdown
# My Page Title Terrace was originally envisioned out of frustration at the massive usability gulf for embedding custom blocks in simple, human-friendly markup formats such as [Markdown](), and capable but complex block-based systems such as [Project Gutenberg](https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/writing-your-first-block-type/) and [Editor.js](https://editorjs.io/saving-data/).
Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad. Heading 3 The Complexity Problem
class mt-8 mb-4
1. Magna id sint consequat quis esse tempor. Markdown
2. Veniam eu id esse occaecat eu. **A simple markdown document:**
3. Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua.
[Put my-custom-component here somehow] CodeBlock markdown
# My Page Title
Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim.
Markdown
**That same document in a *simplified* Editor.js schema:**
CodeBlock javascript
class max-h-[500px] overflow-y-auto
[
{
type: "header",
data: {
level: 1,
text: "My Page Title"
}
},
{
type: "paragraph",
data: {
text: "Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad."
}
},
{
type: "list",
data: {
style: "ordered",
items: [
"Magna id sint consequat quis esse tempor.",
"Veniam eu id esse occaecat eu.",
"Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua."
]
}
},
{
type: "my-custom-component",
data: {
option1: "value",
option2: "value",
text: "Text"
}
},
{
type: "paragraph",
data: {
text: "Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim."
}
}
]
Heading 3 MDX & MDC
class mt-16 mb-4
Markdown
Other attempts, such as [MDX](https://mdxjs.com/) and [MDC](https://content.nuxtjs.org/guide/writing/mdc/) have been made to solve this problem, allowing you to incorporate complex content *inside* markup documents.
However, they suffer from a number of problems:
1. Tightly coupled to the JavaScript ecosystem
2. Lock you out of other markup formats, such as [AsciiDoc](https://asciidoc.org/)
3. Difficult to parse - Markdown was not intended as a general-purpose syntax
4. Data can't be extracted from markup without rendering the entire document to HTML
5. Ugly. Just look at this:
CodeBlock markdown
# My Page Title
Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad.
1. Magna id sint consequat quis esse tempor.
2. Veniam eu id esse occaecat eu.
3. Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua.
[MDX Example]
<MyCustomComponent option1={{'value'}} option2={{'value'}}>
Text
</MyCustomComponent>
[MDC Example]
::MyCustomComponent{option1="value", option2="value"}
Text
::
Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim.
Heading 3 Terrace Prototype
class mt-16 mb-4
Markdown
I first attempted to solve this problem using an [S-Expression](https://en.wikipedia.org/wiki/S-expression)-based syntax for defining blocks.
CodeBlock lisp
(heading
(level 1)
My Page Title
)
(markdown
Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad.
1. Magna id sint consequat quis esse tempor.
2. Veniam eu id esse occaecat eu.
3. Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua.
)
(my-custom-component
(option1 value)
(option2 value)
Text
)
(markdown
Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim.
)
Markdown
While quite flexible and clean-looking, problems became apparent with handling whitespace and escaping parenthesis in text.
The parser quickly became much more extensive than initially envisioned.
Nevertheless, it proved the concept that cleanly combining functional blocks and markup text was quite reasonable.
Not long after, I stumbled upon [Tree Notation](https://treenotation.org) by [Brek Yunits](https://www.breckyunits.com/). Playing around with it, the potential of just *getting rid of the parenthesis* was quite apparent. Simpler syntax for humans to write, and far less work required for parsing & escaping since the only control characters are newlines and spaces:
CodeBlock terrace
heading My Page Title
level 1
markdown
Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad. Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad.
1. Magna id sint consequat quis esse tempor. 1. Magna id sint consequat quis esse tempor.
2. Veniam eu id esse occaecat eu. 2. Veniam eu id esse occaecat eu.
3. Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua. 3. Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua.
my-custom-block [Put my-custom-component here somehow]
option1 value
option2 value
Text
markdown
Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim. Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim.
Markdown Markdown
Ultimately though, using Tree Notation still proved too messy. After working with the grammar system and spreadsheet-style data model for a good while, my gut said all this use case needed was a simple line-based parser. **That same document in a *simplified* Editor.js schema:**
I started Terrace to implement a similar syntax, but with the following goals: CodeBlock javascript
class max-h-[500px] overflow-y-auto
[
{
type: "header",
data: {
level: 1,
text: "My Page Title"
}
},
{
type: "paragraph",
data: {
text: "Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad."
}
},
{
type: "list",
data: {
style: "ordered",
items: [
"Magna id sint consequat quis esse tempor.",
"Veniam eu id esse occaecat eu.",
"Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua."
]
}
},
{
type: "my-custom-component",
data: {
option1: "value",
option2: "value",
text: "Text"
}
},
{
type: "paragraph",
data: {
text: "Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim."
}
}
]
1. Make as few decisions as possible for the user Heading 3 MDX & MDC
2. Be as fast, tiny, and light on resources as possible class mt-16 mb-4
Six or seven parser rewrites later, it finally works mostly how I envisioned it. :) Markdown
Other attempts, such as [MDX](https://mdxjs.com/) and [MDC](https://content.nuxtjs.org/guide/writing/mdc/) have been made to solve this problem, allowing you to incorporate complex content *inside* markup documents.
However, they suffer from a number of problems:
1. Tightly coupled to the JavaScript ecosystem
2. Lock you out of other markup formats, such as [AsciiDoc](https://asciidoc.org/)
3. Difficult to parse - Markdown was not intended as a general-purpose syntax
4. Data can't be extracted from markup without rendering the entire document to HTML
5. Ugly. Just look at this:
CodeBlock markdown
# My Page Title
Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad.
1. Magna id sint consequat quis esse tempor.
2. Veniam eu id esse occaecat eu.
3. Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua.
[MDX Example]
<MyCustomComponent option1={{'value'}} option2={{'value'}}>
Text
</MyCustomComponent>
[MDC Example]
::MyCustomComponent{option1="value", option2="value"}
Text
::
Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim.
Heading 3 Terrace Prototype
class mt-16 mb-4
Markdown
I first attempted to solve this problem using an [S-Expression](https://en.wikipedia.org/wiki/S-expression)-based syntax for defining blocks.
CodeBlock lisp
(heading
(level 1)
My Page Title
)
(markdown
Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad.
1. Magna id sint consequat quis esse tempor.
2. Veniam eu id esse occaecat eu.
3. Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua.
)
(my-custom-component
(option1 value)
(option2 value)
Text
)
(markdown
Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim.
)
Markdown
While quite flexible and clean-looking, problems became apparent with handling whitespace and escaping parenthesis in text.
The parser quickly became much more extensive than initially envisioned.
Nevertheless, it proved the concept that cleanly combining functional blocks and markup text was quite reasonable.
Not long after, I stumbled upon [Tree Notation](https://treenotation.org) by [Brek Yunits](https://www.breckyunits.com/). Playing around with it, the potential of just *getting rid of the parenthesis* was quite apparent. Simpler syntax for humans to write, and far less work required for parsing & escaping since the only control characters are newlines and spaces:
CodeBlock terrace
heading My Page Title
level 1
markdown
Occaecat fugiat est ullamco aliqua ea dolor nostrud. Reprehenderit nisi minim sit commodo deserunt ullamco deserunt aute ex exercitation Lorem deserunt ad.
1. Magna id sint consequat quis esse tempor.
2. Veniam eu id esse occaecat eu.
3. Minim commodo nostrud eiusmod excepteur ea sint in enim esse aliqua.
my-custom-block
option1 value
option2 value
Text
markdown
Dolor adipisicing amet aliquip nulla occaecat Lorem excepteur veniam. Voluptate pariatur sint anim tempor aliquip in. Id nulla est irure officia occaecat enim.
Markdown
Ultimately though, using Tree Notation still proved too messy. After working with the grammar system and spreadsheet-style data model for a good while, my gut said all this use case needed was a simple line-based parser.
I started Terrace to implement a similar syntax, but with the following goals:
1. Make as few decisions as possible for the user
2. Be as fast, tiny, and light on resources as possible
Six or seven parser rewrites later, it finally works mostly how I envisioned it. :)
Section dark Section dark
class max-w-prose class flex flex-col md:flex-row gap-16
Heading 2 Development Goals Block
class w-1/3
Markdown Block
class prose-invert class max-w-prose
Terrace development is guided by the following goals.
- **Tiny, primitive core - no “framework”** Heading 2 Development Goals
- Use the most boring patterns possible for implementing the core library.
- Avoid dependencies
- Easily port Terrace in any language or environment
- **Avoid dynamic allocation**
- Since we can work directly off of string slices without the need for ASTs and escaping systems, might as well avoid dynamic allocations altogether!
- **Minimize assumptions**
- Let people use Terrace as a building block for all sorts of languages
Make note of this before submitting change requests. If your changes don't fit these goals, they may be denied. In which case, you could try building a separate library on top of the Terrace cor. Markdown
class prose-invert
Terrace development is guided by the following goals.
Footer - **Tiny, primitive core - no “framework”**
- Use the most boring patterns possible for implementing the core library.
- Avoid dependencies
- Easily port Terrace in any language or environment
- **Avoid dynamic allocation**
- Since we can work directly off of string slices without the need for ASTs and escaping systems, might as well avoid dynamic allocations altogether!
- **Minimize assumptions**
- Let people use Terrace as a building block for all sorts of languages
Make note of this before submitting change requests. If your changes don't fit these goals, they may be denied. In which case, you could try building a separate library on top of the Terrace cor.
Footer

View File

@ -5,10 +5,12 @@ description
Terrace gets out of your way to let you just write Terrace gets out of your way to let you just write
Section light Section light
class pt-40 md:pt-36 pb-48 md:pb-64 flex flex-col gap-16 md:flex-row md:gap-48 class pt-24 flex flex-col gap-16 md:flex-row lg:gap-48
Block Block
class flex flex-col gap-8 w-full items-start class flex flex-col gap-8 w-full items-start
Logo light Logo light
class hidden lg:flex
Markdown Markdown
class prose-ul:list-none class prose-ul:list-none
A simple structured data syntax for A simple structured data syntax for
@ -74,7 +76,7 @@ Section dark
Heading 2 Uses Heading 2 Uses
Block Block
class flex flex-col space-between gap-16 md:flex-row md:gap-48 class flex flex-col space-between gap-16 md:flex-row lg:gap-48
Block Block
class max-w-prose class max-w-prose
@ -122,7 +124,7 @@ Section light
Heading 2 Core Heading 2 Core
Block Block
class flex flex-col space-between gap-16 md:flex-row md:gap-48 class flex flex-col space-between gap-16 md:flex-row lg:gap-48
Block Block
Heading 3 Tiny - <strong>Really Tiny</strong> Heading 3 Tiny - <strong>Really Tiny</strong>
@ -165,7 +167,7 @@ Section dark
Heading 2 Learn More Heading 2 Learn More
Block Block
class flex flex-col space-between gap-16 md:flex-row md:gap-48 class flex flex-col space-between gap-16 md:flex-row lg:gap-48
Block Block
class max-w-prose class max-w-prose

View File

@ -4,7 +4,7 @@ module.exports = async function (doc, rootLevel, pageData) {
const { next, line, match, tail, level, head } = doc const { next, line, match, tail, level, head } = doc
const headingLevel = tail().split(' ')[0] const headingLevel = +tail().split(' ')[0]
const text = tail().split(' ').slice(1).join(' ') const text = tail().split(' ').slice(1).join(' ')
const slug = slugify(text) const slug = slugify(text)
@ -13,7 +13,8 @@ module.exports = async function (doc, rootLevel, pageData) {
level: headingLevel, level: headingLevel,
text, text,
slug, slug,
class: '' class: '',
children: []
} }
while (await next(rootLevel)) { while (await next(rootLevel)) {

View File

@ -0,0 +1,23 @@
const { contentAsText } = require('../helpers.js')
module.exports = async function (doc, rootLevel) {
const { next, line, match, tail, level, head } = doc
const node = {
type: head(),
variant: tail() || 'neutral',
class: '',
href: '',
text: ''
}
while (await next(rootLevel)) {
if (match('class')) node.class = tail()
else if (match('href')) node.href = tail()
else {
node.text = await contentAsText(doc, rootLevel, true)
}
}
return node
}

View File

@ -0,0 +1,14 @@
module.exports = async function (doc, rootLevel) {
const { next, head, tail, match } = doc
const node = {
type: head(),
class: '',
}
while (await next(rootLevel)) {
if (match('class')) node.class = tail()
}
return node
}

View File

@ -5,6 +5,7 @@ module.exports.Section = async (doc, rootLevel, ...args) => {
const variant = doc.tail() const variant = doc.tail()
return { variant, ...(await parseNode(doc, rootLevel, ...args)) } return { variant, ...(await parseNode(doc, rootLevel, ...args)) }
} }
module.exports.TableOfContents = require('./TableOfContents.js')
module.exports.Heading = require('./Heading.js') module.exports.Heading = require('./Heading.js')
module.exports.Button = require('./Button.js') module.exports.Button = require('./Button.js')
module.exports.Icon = require('./Icon.js') module.exports.Icon = require('./Icon.js')
@ -12,9 +13,6 @@ module.exports.Icon = require('./Icon.js')
module.exports.Markdown = require('./Markdown.js') module.exports.Markdown = require('./Markdown.js')
module.exports.CodeBlock = require('./CodeBlock.js') module.exports.CodeBlock = require('./CodeBlock.js')
module.exports.CodeExample = require('./CodeExample.js') module.exports.CodeExample = require('./CodeExample.js')
module.exports.Logo = doc => ({ module.exports.Logo = require('./Logo.js')
type: `Logo`,
variant: doc.tail() || 'light'
})
module.exports.Footer = require('./Footer.js') module.exports.Footer = require('./Footer.js')

View File

@ -27,7 +27,20 @@ module.exports = async function(doc) {
} }
} }
console.dir(pageData, { depth: null }) // Structure headings into tree.
pageData.headings.forEach((heading, index) => {
let parent = null
for (let i = index; i > 0; --i) {
if (pageData.headings[i].level === heading.level - 1) {
parent = pageData.headings[i]
}
}
if (parent) parent.children.push(heading)
})
pageData.headings = pageData.headings.filter(h => h.level === 2)
console.dir(pageData.headings, { depth: null })
return pageData return pageData
} }