Add 'Core' section.
This commit is contained in:
parent
df3aa36e26
commit
381aec4ba4
@ -1,11 +1,16 @@
|
|||||||
const HighlightJS = require('highlight.js')
|
|
||||||
const EleventyVitePlugin = require('@11ty/eleventy-plugin-vite')
|
const EleventyVitePlugin = require('@11ty/eleventy-plugin-vite')
|
||||||
|
const EleventyGoogleFonts = require("eleventy-google-fonts");
|
||||||
|
const EleventyFeatherIcons = require('eleventy-plugin-feathericons');
|
||||||
|
|
||||||
|
const HighlightJS = require('highlight.js')
|
||||||
const { useDocument } = require('@terrace/js/document')
|
const { useDocument } = require('@terrace/js/document')
|
||||||
const { createFileReader } = require('@terrace/js/readers/node-readline')
|
const { createFileReader } = require('@terrace/js/readers/node-readline')
|
||||||
const parsePage = require('./parser/page.js')
|
const parsePage = require('./parser/page.js');
|
||||||
|
|
||||||
module.exports = function (config) {
|
module.exports = function (config) {
|
||||||
config.addPlugin(EleventyVitePlugin)
|
config.addPlugin(EleventyVitePlugin)
|
||||||
|
config.addPlugin(EleventyGoogleFonts)
|
||||||
|
config.addPlugin(EleventyFeatherIcons)
|
||||||
|
|
||||||
config.addPassthroughCopy('src/public')
|
config.addPassthroughCopy('src/public')
|
||||||
config.addPassthroughCopy('src/styles')
|
config.addPassthroughCopy('src/styles')
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
"@11ty/eleventy-plugin-vite": "^4.0.0",
|
"@11ty/eleventy-plugin-vite": "^4.0.0",
|
||||||
"@tailwindcss/typography": "^0.5.9",
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
"@terrace/js": "workspace:*",
|
"@terrace/js": "workspace:*",
|
||||||
|
"eleventy-google-fonts": "^0.1.0",
|
||||||
|
"eleventy-plugin-feathericons": "^1.0.1",
|
||||||
"highlight.js": "^11.7.0",
|
"highlight.js": "^11.7.0",
|
||||||
"marked": "^4.2.12",
|
"marked": "^4.2.12",
|
||||||
"tailwindcss": "^3.2.6",
|
"tailwindcss": "^3.2.6",
|
||||||
|
@ -4,17 +4,18 @@ const languages = ['terrace', 'json', 'yaml', 'toml', 'javascript', 'typescript'
|
|||||||
|
|
||||||
module.exports = async (doc, rootLevel) => {
|
module.exports = async (doc, rootLevel) => {
|
||||||
const { next, level, line, head, tail } = doc
|
const { next, level, line, head, tail } = doc
|
||||||
const codeExample = {
|
|
||||||
type: 'CodeExample',
|
const node = {
|
||||||
|
type: head(),
|
||||||
languages: {}
|
languages: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (await next(rootLevel)) {
|
while (await next(rootLevel)) {
|
||||||
const languageLevel = level()
|
const languageLevel = level()
|
||||||
if (languages.includes(head())) {
|
if (languages.includes(head())) {
|
||||||
codeExample.languages[head()] = await contentAsText(doc, languageLevel)
|
node.languages[head()] = await contentAsText(doc, languageLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return codeExample
|
return node
|
||||||
}
|
}
|
||||||
|
16
docs/parser/nodes/Header.js
Normal file
16
docs/parser/nodes/Header.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
module.exports = async function (doc, rootLevel) {
|
||||||
|
const { next, line, match, tail, level, head } = doc
|
||||||
|
|
||||||
|
const node = {
|
||||||
|
type: head(),
|
||||||
|
level: tail().split(' ')[0],
|
||||||
|
text: tail().split(' ').slice(1).join(' '),
|
||||||
|
class: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
while (await next(rootLevel)) {
|
||||||
|
if (match('class')) node.class = tail()
|
||||||
|
}
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
10
docs/parser/nodes/Icon.js
Normal file
10
docs/parser/nodes/Icon.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module.exports = async function (doc) {
|
||||||
|
const { head, tail } = doc
|
||||||
|
|
||||||
|
const node = {
|
||||||
|
type: head(),
|
||||||
|
icon: tail()
|
||||||
|
}
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
const { contentAsText } = require('../helpers.js')
|
const { contentAsText } = require('../helpers.js')
|
||||||
const marked = require('marked')
|
const marked = require('marked')
|
||||||
|
|
||||||
module.exports = async (...args) => {
|
module.exports = async (doc, rootLevel) => {
|
||||||
return {
|
return {
|
||||||
type: `Markdown`,
|
type: doc.head(),
|
||||||
text: marked.parse(await contentAsText(...args))
|
text: marked.parse(await contentAsText(doc, rootLevel))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
const parseNode = require('./Node.js')
|
const parseNode = require('./Node.js')
|
||||||
|
|
||||||
|
module.exports.Div = parseNode
|
||||||
module.exports.Section = async (doc, rootLevel) => {
|
module.exports.Section = async (doc, rootLevel) => {
|
||||||
const variant = doc.tail()
|
const variant = doc.tail()
|
||||||
return { variant, ...(await parseNode(doc, rootLevel)) }
|
return { variant, ...(await parseNode(doc, rootLevel)) }
|
||||||
}
|
}
|
||||||
|
module.exports.Header = require('./Header.js')
|
||||||
|
module.exports.Button = require('./Button.js')
|
||||||
|
module.exports.Icon = require('./Icon.js')
|
||||||
|
|
||||||
module.exports.Div = parseNode
|
module.exports.Markdown = require('./Markdown.js')
|
||||||
|
module.exports.CodeExample = require('./CodeExample.js')
|
||||||
module.exports.Logo = doc => ({
|
module.exports.Logo = doc => ({
|
||||||
type: `Logo`,
|
type: `Logo`,
|
||||||
variant: doc.tail() || 'light'
|
variant: doc.tail() || 'light'
|
||||||
})
|
})
|
||||||
module.exports.Markdown = require('./Markdown.js')
|
|
||||||
module.exports.CodeExample = require('./CodeExample.js')
|
|
||||||
module.exports.Button = require('./Button.js')
|
|
||||||
|
@ -4,12 +4,10 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
<meta name="description" content="{{ description | join(' ') }}"/>
|
<meta name="description" content="{{ description | join(' ') }}"/>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@300;400;500&display=swap" rel="stylesheet">
|
{% eleventyGoogleFonts 'https://fonts.googleapis.com/css2?family=Fredoka:wght@300;400;500&display=swap' %}
|
||||||
</head>
|
</head>
|
||||||
<body class="text-base">
|
<body class="text-base">
|
||||||
{{ Node('Navbar') }}
|
{{ Node('Navbar') }}
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
href="{{ node.href }}"
|
href="{{ node.href }}"
|
||||||
target="{{ node.target }}"
|
target="{{ node.target }}"
|
||||||
{% if node.variant == "primary" %}
|
{% if node.variant == "primary" %}
|
||||||
class="{{ commonClasses }} bg-gradient-to-b from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-600 active:from-primary-600 active:to-primary-500"
|
class="{{ node.class }} {{ commonClasses }} bg-gradient-to-b from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-600 active:from-primary-600 active:to-primary-500"
|
||||||
{% elseif node.variant == 'neutral' %}
|
{% elseif node.variant == 'neutral' %}
|
||||||
class="{{ commonClasses }} bg-gradient-to-b from-neutral-500 to-neutral-800"
|
class="{{ node.class }} {{ commonClasses }} bg-gradient-to-b from-neutral-500 to-neutral-800"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
>
|
>
|
||||||
{{ node.text | safe }}
|
{{ node.text | safe }}
|
||||||
|
14
docs/src/_includes/nodes/Header.njk
Normal file
14
docs/src/_includes/nodes/Header.njk
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% set levelClasses = {
|
||||||
|
'2': 'text-5xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600 mb-12',
|
||||||
|
'3': 'text-2xl font-light mb-2'
|
||||||
|
} %}
|
||||||
|
|
||||||
|
{% macro render(node) %}
|
||||||
|
<h{{ node.level }}
|
||||||
|
{% if levelClasses[node.level] %}
|
||||||
|
class="{{ levelClasses[node.level] }} {{ node.class }}"
|
||||||
|
{% endif %}
|
||||||
|
>
|
||||||
|
{{ node.text | safe }}
|
||||||
|
</h{{ node.level }}>
|
||||||
|
{% endmacro %}
|
3
docs/src/_includes/nodes/Icon.njk
Normal file
3
docs/src/_includes/nodes/Icon.njk
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{% macro render(node) %}
|
||||||
|
{% feather node.icon %}
|
||||||
|
{% endmacro %}
|
@ -1,13 +1,13 @@
|
|||||||
{% macro render(node) %}
|
{% macro render(node) %}
|
||||||
{% if node.variant != 'small' %}
|
{% if node.variant == 'small' %}
|
||||||
<div class="flex gap-4 items-center">
|
|
||||||
<img src="/logo.png" class="w-16 h-16" alt=""/>
|
|
||||||
<span class="text-5xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600">Terrace</span>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="flex gap-2 items-center">
|
<div class="flex gap-2 items-center">
|
||||||
<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 %}
|
||||||
|
<div class="flex gap-4 items-center">
|
||||||
|
<img src="/logo.png" class="w-16 h-16" alt=""/>
|
||||||
|
<h1 class="text-5xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600">Terrace</h1>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% macro render(node) %}
|
{% macro render(node) %}
|
||||||
<div class="prose prose-neutral prose-lg text-base prose-p:my-2 prose-ul:my-2 prose-ul:list-none prose-li:my-0">
|
<div class="prose prose-neutral prose-lg text-base prose-p:mb-4 prose-ul:my-2 prose-ul:list-none prose-li:my-0 text-current">
|
||||||
{{ node.text | safe }}
|
{{ node.text | safe }}
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{% from "./Node.njk" import Node %}
|
{% from "./Node.njk" import Node %}
|
||||||
|
|
||||||
{% macro render(node) %}
|
{% macro render(node) %}
|
||||||
<nav class="bg-neutral-800 text-neutral-50 h-16 flex items-center">
|
<nav class="relative bg-neutral-800 text-neutral-50 h-20 flex items-center">
|
||||||
<div class="container mx-auto flex items-center space-between">
|
<div class="container mx-auto flex items-center space-between">
|
||||||
<a href="/" class="w-full">
|
<a href="/" class="w-full">
|
||||||
{{ Node('Logo', { variant: 'small' }) }}
|
{{ Node('Logo', { variant: 'small' }) }}
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
{% from "./Node.njk" import Node %}
|
{% from "./Node.njk" import Node %}
|
||||||
|
|
||||||
{% set variants = {
|
{% set variants = {
|
||||||
light: "bg-gradient-to-t from-neutral-50/50 to-neutral-50",
|
light: "bg-gradient-to-b from-neutral-50 to-neutral-50/50",
|
||||||
dark: "bg-gradient-to-t from-neutral-900 to-neutral-800"
|
dark: "
|
||||||
|
bg-gradient-to-b from-neutral-800 to-neutral-900 text-neutral-50
|
||||||
|
"
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
{% macro render(node) %}
|
{% macro render(node) %}
|
||||||
<section class="{{ variants[node.variant] }} {{ node.class }} py-32">
|
<svg class="w-full -mt-[55px] {{ 'text-neutral-50' if node.variant == 'light' else 'text-neutral-800' }}" viewBox="0 0 1920 55">
|
||||||
<div class="container mx-auto flex gap-48">
|
<path d="M0 55H1920V6.99994C1811 55 1150 55 403.5 6.99994C141.541 -9.84407 0 6.99996 0 55Z" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
<section class="{{ variants[node.variant] }}">
|
||||||
|
<div class="container mx-auto py-32 {{ node.class }}">
|
||||||
{% for child in node.children %}
|
{% for child in node.children %}
|
||||||
{{ Node(child.type, child) }}
|
{{ Node(child.type, child) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -5,7 +5,7 @@ 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 pb-64
|
class pb-64 flex gap-48
|
||||||
Div
|
Div
|
||||||
class flex flex-col gap-8 w-full items-start
|
class flex flex-col gap-8 w-full items-start
|
||||||
Logo light
|
Logo light
|
||||||
@ -67,3 +67,93 @@ Section light
|
|||||||
|
|
||||||
Terrace gets out of your way to let you
|
Terrace gets out of your way to let you
|
||||||
- **just write**"""
|
- **just write**"""
|
||||||
|
|
||||||
|
Section dark
|
||||||
|
class pt-8
|
||||||
|
Header 2 Uses
|
||||||
|
|
||||||
|
Div
|
||||||
|
class flex gap-48 space-between
|
||||||
|
|
||||||
|
Div
|
||||||
|
class max-w-prose
|
||||||
|
Div
|
||||||
|
class flex gap-4 items-center mb-4
|
||||||
|
Icon settings
|
||||||
|
Header 3 Configuration
|
||||||
|
class mb-0
|
||||||
|
Markdown
|
||||||
|
Terrace’s concise syntax (or lack thereof)
|
||||||
|
makes it a great fit for configuration files.
|
||||||
|
Less verbose than JSON without the wild unpredictability and hidden syntax pitfalls that come with YAML.
|
||||||
|
|
||||||
|
If you wish, you can build in your own input validation and type casting while parsing configuration files.
|
||||||
|
|
||||||
|
Div
|
||||||
|
class max-w-prose
|
||||||
|
Div
|
||||||
|
class flex gap-4 items-center mb-4
|
||||||
|
Icon feather
|
||||||
|
Header 3 Content Authoring
|
||||||
|
class mb-0
|
||||||
|
Markdown
|
||||||
|
An unopinionated, indent-based syntax allows fulls blocks of plain-text or markup languages (such as markdown) to be embedded inside of Terrace documents.
|
||||||
|
|
||||||
|
This enables effortless mixing of data, prose, and functional blocks in human-written documents. No more need for clumsy frontmatter or custom Markdown extensions!
|
||||||
|
|
||||||
|
Div
|
||||||
|
class max-w-prose
|
||||||
|
Div
|
||||||
|
class flex gap-4 items-center mb-4
|
||||||
|
Icon code
|
||||||
|
Header 3 Domain-Specific Languages
|
||||||
|
class mb-0
|
||||||
|
Markdown
|
||||||
|
Terrace documents, at their core, are effectively their own AST (Abstract Syntax Tree). Every time you parse a Terrace document you’ve essentially parsed your own DSL.
|
||||||
|
|
||||||
|
The core libraries are designed with this in mind, exposing ergonomic tools while getting out of your way as much as possible, so you can make Terrace your own.
|
||||||
|
|
||||||
|
Button primary
|
||||||
|
class inline-block mt-8
|
||||||
|
See Examples
|
||||||
|
|
||||||
|
Section light
|
||||||
|
class pt-8
|
||||||
|
Header 2 Core
|
||||||
|
|
||||||
|
Div
|
||||||
|
class flex gap-48 space-between
|
||||||
|
|
||||||
|
Div
|
||||||
|
Header 3 Tiny - <strong>Really Tiny</strong>
|
||||||
|
Markdown
|
||||||
|
The C version of the core parser is ~30 lines. Most other implementations are of comparable size.
|
||||||
|
|
||||||
|
Header 3 Easy to Implement
|
||||||
|
class mt-16
|
||||||
|
Markdown
|
||||||
|
Need to use Terrace in another runtime? The tiny core and reliance on rudimentary control structures makes that a cinch!
|
||||||
|
|
||||||
|
Div
|
||||||
|
Header 3 Zero Dependencies
|
||||||
|
Markdown
|
||||||
|
All Terrace implementations rely only on the built-ins of their language. The header-only C core has no dependencies, not even libc.
|
||||||
|
|
||||||
|
Header 3 No Dynamic Memory
|
||||||
|
class mt-16
|
||||||
|
Markdown
|
||||||
|
Terrace allocates no dynamic memory of its own, working entirely on the stack. A great fit for resource-constrained environments.
|
||||||
|
|
||||||
|
Div
|
||||||
|
Header 3 Unopinionated
|
||||||
|
Markdown
|
||||||
|
Terrace makes as few assumptions as possible about how you intend to use it, leaving you with the tools you need to use it as you see fit.
|
||||||
|
|
||||||
|
Header 3 Available in 3+ languages
|
||||||
|
class mt-16
|
||||||
|
Markdown
|
||||||
|
At launch, Terrace has a reference C implementation, a TypeScript/JavaScript implementation, and a Python version available as well. We’ll be adding more as time permits!
|
||||||
|
|
||||||
|
Button primary
|
||||||
|
class inline-block mt-8
|
||||||
|
Add a Language
|
||||||
|
@ -30,7 +30,7 @@ module.exports = {
|
|||||||
600: '#1F609A',
|
600: '#1F609A',
|
||||||
700: '#17456F',
|
700: '#17456F',
|
||||||
800: '#0E2B45',
|
800: '#0E2B45',
|
||||||
900: '#05111B'
|
900: '#0C2236'
|
||||||
},
|
},
|
||||||
warn: colors.orange,
|
warn: colors.orange,
|
||||||
danger: colors.red,
|
danger: colors.red,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user