Move to custom SSG instead of eleventy.
This commit is contained in:
20
docs/renderer/layout.njk
Normal file
20
docs/renderer/layout.njk
Normal file
@@ -0,0 +1,20 @@
|
||||
<!doctype html>
|
||||
{% from "nodes/Node.njk" import Node %}
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ page.title }}</title>
|
||||
<meta name="description" content="{{ page.description | join(' ') }}"/>
|
||||
<link rel="stylesheet" href="/main.css"/>
|
||||
<link rel="stylesheet" href="/public/styles/highlightjs-theme.css"/>
|
||||
{{ googleFonts('https://fonts.googleapis.com/css2?family=Fredoka:wght@300;400;500&display=swap') }}
|
||||
</head>
|
||||
<body class="text-base pt-16">
|
||||
{{ Node('Navbar', {}, { headings: page.headings, url: url }) }}
|
||||
{% for child in page.children %}
|
||||
{{ Node(child.type, child, { headings: page.headings, url: url }) }}
|
||||
{% endfor %}
|
||||
</body>
|
||||
</html>
|
||||
9
docs/renderer/nodes/Block.njk
Normal file
9
docs/renderer/nodes/Block.njk
Normal file
@@ -0,0 +1,9 @@
|
||||
{% from "./Node.njk" import Node %}
|
||||
|
||||
{% macro render(node, page) %}
|
||||
<div class="{{ node.class }}">
|
||||
{% for child in node.children %}
|
||||
{{ Node(child.type, child, page) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
14
docs/renderer/nodes/Button.njk
Normal file
14
docs/renderer/nodes/Button.njk
Normal file
@@ -0,0 +1,14 @@
|
||||
{% set commonClasses = "px-6 py-2 md:px-12 md:py-3 text-white rounded-md w-auto whitespace-nowrap not-prose" %}
|
||||
{% macro render(node) %}
|
||||
<a
|
||||
href="{{ node.href }}"
|
||||
target="{{ node.target }}"
|
||||
{% if node.variant == "primary" %}
|
||||
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' %}
|
||||
class="{{ node.class }} {{ commonClasses }} bg-gradient-to-b from-neutral-500 to-neutral-800"
|
||||
{% endif %}
|
||||
>
|
||||
{{ node.text | safe }}
|
||||
</a>
|
||||
{% endmacro %}
|
||||
9
docs/renderer/nodes/CodeBlock.njk
Normal file
9
docs/renderer/nodes/CodeBlock.njk
Normal file
@@ -0,0 +1,9 @@
|
||||
{% macro render(node) %}
|
||||
<pre
|
||||
class="
|
||||
my-8 p-4
|
||||
bg-neutral-900 text-neutral-50 rounded-md whitespace-pre-wrap text-sm
|
||||
{{ node.class }}
|
||||
"
|
||||
>{{ node.text | highlight(node.language) | safe }}</pre>
|
||||
{% endmacro %}
|
||||
52
docs/renderer/nodes/CodeExample.njk
Normal file
52
docs/renderer/nodes/CodeExample.njk
Normal file
@@ -0,0 +1,52 @@
|
||||
{%
|
||||
set languageMeta = {
|
||||
'terrace': { name: 'Terrace', icon: '<svg viewBox="0 0 64 64"><g clip-path="url(#a)"><rect width="64" height="64" fill="#fff" rx="8"/><mask id="b" width="64" height="64" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha"><path fill="#000" d="M0 0h64v64H0V0Z"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M0 0h64v64H0V0Z"/><circle cx="4" cy="14" r="16" fill="url(#d)"/><circle cx="16" cy="27" r="15" fill="url(#e)"/><circle cx="30" cy="50" r="25" fill="url(#f)"/><circle cx="52" cy="57" r="16" fill="url(#g)"/><circle cx=".5" cy="30.5" r="11.5" fill="url(#h)"/><circle cx="16" cy="35" r="8" fill="url(#i)"/><circle cx="37" cy="45" r="13" fill="url(#j)"/><circle cx="15.5" cy="61.5" r="28.5" fill="url(#k)"/><circle cx="40" cy="61" r="8" fill="url(#l)"/><circle cx="23" cy="73" r="23" fill="url(#m)"/></g></g><defs><radialGradient id="d" cx="0" cy="0" r="1" gradientTransform="rotate(73.301 5.218 12.225) scale(23.8636 26.8465)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="e" cx="0" cy="0" r="1" gradientTransform="rotate(73.301 1.693 26.631) scale(22.3721 25.1686)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="f" cx="0" cy="0" r="1" gradientTransform="matrix(10.71426 35.71429 -40.17862 12.05355 47.857 33.929)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="g" cx="0" cy="0" r="1" gradientTransform="rotate(73.301 .322 65.982) scale(23.8636 26.8465)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="h" cx="0" cy="0" r="1" gradientTransform="matrix(4.92855 16.42854 -18.48212 5.54462 8.714 23.107)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="i" cx="0" cy="0" r="1" gradientTransform="rotate(73.301 -9.207 29.52) scale(11.9318 13.4232)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="j" cx="0" cy="0" r="1" gradientTransform="matrix(5.5714 18.5714 -20.89288 6.26785 46.286 36.643)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="k" cx="0" cy="0" r="1" gradientTransform="rotate(73.301 -11.088 45.686) scale(42.507 47.8203)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="l" cx="0" cy="0" r="1" gradientTransform="rotate(73.301 -14.68 58.65) scale(11.9318 13.4232)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><radialGradient id="m" cx="0" cy="0" r="1" gradientTransform="rotate(73.301 -19.407 55.604) scale(34.3039 38.5918)" gradientUnits="userSpaceOnUse"><stop stop-color="#5CCA53"/><stop offset="1" stop-color="#22701B"/></radialGradient><linearGradient id="c" x1="31" x2="32" y1="0" y2="64" gradientUnits="userSpaceOnUse"><stop stop-color="#70B8FB"/><stop offset="1" stop-color="#99C9F5" stop-opacity=".27"/></linearGradient><clipPath id="a"><rect width="64" height="64" fill="#fff" rx="8"/></clipPath></defs></svg>' },
|
||||
'json': { name: 'JSON', icon: '<svg viewBox="0 0 160 160"><defs><linearGradient id="linearGradient8385"><stop offset="0"/><stop stop-color="#fff" offset="1"/></linearGradient><linearGradient id="linearGradient3002" x1="-553.27" x2="-666.12" y1="525.91" y2="413.05" gradientTransform="matrix(.99884 0 0 .9987 689.01 -388.84)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8385"/><linearGradient id="linearGradient3005" x1="-666.12" x2="-553.27" y1="413.04" y2="525.91" gradientTransform="matrix(.99884 0 0 .9987 689.01 -388.84)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8385"/></defs><g fill-rule="evenodd"><path d="m79.865 119.1c35.398 48.255 70.04-13.469 69.989-50.587-0.0602-43.886-44.541-68.414-70.018-68.414-40.892 0-79.836 33.796-79.836 80.036 0 51.396 44.64 79.865 79.836 79.865-7.9645-1.1468-34.506-6.834-34.863-67.967-0.23987-41.347 13.488-57.866 34.805-50.599 0.47743 0.17707 23.514 9.2645 23.514 38.951 0 29.56-23.427 38.715-23.427 38.715z" color="#000000" fill="url(#linearGradient3005)"/><path d="m79.823 41.401c-23.39-8.0619-52.043 11.216-52.043 49.829 0 63.048 46.721 68.77 52.384 68.77 40.892 0 79.836-33.796 79.836-80.036 0-51.396-44.64-79.865-79.836-79.865 9.7481-1.35 52.541 10.55 52.541 69.037 0 38.141-31.953 58.905-52.735 50.033-0.47743-0.17707-23.514-9.2645-23.514-38.951 0-29.56 23.367-38.818 23.367-38.818z" color="#000000" fill="url(#linearGradient3002)"/></g></svg>' },
|
||||
'yaml': { name: 'YAML', icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 470.647" class="bg-white p-[1px]"><polygon id="Y" points="235.793 0 143.978 137.674 143.978 224.949 87.702 224.949 87.702 137.674 0 0 63.25 0 119.018 88.646 175.243 0 235.793 0 235.793 0"/><path id="A" fill="#cb171e" d="M330.294,175.451h-101.861l-20.717,50.024h-45.106l95.38,-224.949h46.137l91.51,224.949h-48.2l-17.144,-50.024zm-16.92,-44.911l-31.226,-82.55l-34.837,82.55h66.063z"/><polygon id="M" points="87.701 250.177 87.701 470.647 135.004 470.647 135.004 318.569 184.509 420.789 221.743 420.789 272.939 314.976 272.939 470.602 318.318 470.602 318.318 250.177 256.358 250.177 201.381 349.883 149.021 250.177 87.701 250.177 87.701 250.177"/><polygon id="L" points="512 422.735 395.638 422.735 395.638 250.125 347.442 250.125 347.442 469.647 512 469.647 512 422.737 512 422.735"/></svg>' },
|
||||
'toml': { name: 'TOML', icon: '<svg viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><g><polygon class="fill-current text-orange-800" points="99.2359551 -7.08546829e-15 99.2359551 14.3820225 112.179775 14.3820225 112.179775 113.617978 99.2359551 113.617978 99.2359551 128 128 128 128 0"></polygon><polygon class="fill-current text-white" points="32.3595506 41.7078652 32.3595506 25.8876404 95.6404494 25.8876404 95.6404494 41.7078652 71.9101124 41.7078652 71.9101124 110.741573 56.0898876 110.741573 56.0898876 41.7078652"></polygon><polygon class="fill-current text-orange-800" points="28.7640449 0 28.7640449 14.3820225 15.8202247 14.3820225 15.8202247 113.617978 28.7640449 113.617978 28.7640449 128 0 128 0 0"></polygon></g></svg>' },
|
||||
'c': { name: 'C', icon: '<svg viewBox="0 0 128 128"><path fill="#659AD3" d="M115.4 30.7L67.1 2.9c-.8-.5-1.9-.7-3.1-.7-1.2 0-2.3.3-3.1.7l-48 27.9c-1.7 1-2.9 3.5-2.9 5.4v55.7c0 1.1.2 2.4 1 3.5l106.8-62c-.6-1.2-1.5-2.1-2.4-2.7z"></path><path fill="#03599C" d="M10.7 95.3c.5.8 1.2 1.5 1.9 1.9l48.2 27.9c.8.5 1.9.7 3.1.7 1.2 0 2.3-.3 3.1-.7l48-27.9c1.7-1 2.9-3.5 2.9-5.4V36.1c0-.9-.1-1.9-.6-2.8l-106.6 62z"></path><path fill="#fff" d="M85.3 76.1C81.1 83.5 73.1 88.5 64 88.5c-13.5 0-24.5-11-24.5-24.5s11-24.5 24.5-24.5c9.1 0 17.1 5 21.3 12.5l13-7.5c-6.8-11.9-19.6-20-34.3-20-21.8 0-39.5 17.7-39.5 39.5s17.7 39.5 39.5 39.5c14.6 0 27.4-8 34.2-19.8l-12.9-7.6z"></path></svg>' },
|
||||
'javascript': { name: 'JavaScript', icon: '<svg viewBox="0 0 128 128"><path fill="#F0DB4F" d="M1.408 1.408h125.184v125.185H1.408z"></path><path fill="#323330" d="M116.347 96.736c-.917-5.711-4.641-10.508-15.672-14.981-3.832-1.761-8.104-3.022-9.377-5.926-.452-1.69-.512-2.642-.226-3.665.821-3.32 4.784-4.355 7.925-3.403 2.023.678 3.938 2.237 5.093 4.724 5.402-3.498 5.391-3.475 9.163-5.879-1.381-2.141-2.118-3.129-3.022-4.045-3.249-3.629-7.676-5.498-14.756-5.355l-3.688.477c-3.534.893-6.902 2.748-8.877 5.235-5.926 6.724-4.236 18.492 2.975 23.335 7.104 5.332 17.54 6.545 18.873 11.531 1.297 6.104-4.486 8.08-10.234 7.378-4.236-.881-6.592-3.034-9.139-6.949-4.688 2.713-4.688 2.713-9.508 5.485 1.143 2.499 2.344 3.63 4.26 5.795 9.068 9.198 31.76 8.746 35.83-5.176.165-.478 1.261-3.666.38-8.581zM69.462 58.943H57.753l-.048 30.272c0 6.438.333 12.34-.714 14.149-1.713 3.558-6.152 3.117-8.175 2.427-2.059-1.012-3.106-2.451-4.319-4.485-.333-.584-.583-1.036-.667-1.071l-9.52 5.83c1.583 3.249 3.915 6.069 6.902 7.901 4.462 2.678 10.459 3.499 16.731 2.059 4.082-1.189 7.604-3.652 9.448-7.401 2.666-4.915 2.094-10.864 2.07-17.444.06-10.735.001-21.468.001-32.237z"></path></svg>' },
|
||||
'typescript': { name: 'TypeScript', icon: '<svg viewBox="0 0 128 128"><path fill="#fff" d="M22.67 47h99.67v73.67H22.67z"></path><path data-name="original" fill="#007acc" d="M1.5 63.91v62.5h125v-125H1.5zm100.73-5a15.56 15.56 0 017.82 4.5 20.58 20.58 0 013 4c0 .16-5.4 3.81-8.69 5.85-.12.08-.6-.44-1.13-1.23a7.09 7.09 0 00-5.87-3.53c-3.79-.26-6.23 1.73-6.21 5a4.58 4.58 0 00.54 2.34c.83 1.73 2.38 2.76 7.24 4.86 8.95 3.85 12.78 6.39 15.16 10 2.66 4 3.25 10.46 1.45 15.24-2 5.2-6.9 8.73-13.83 9.9a38.32 38.32 0 01-9.52-.1 23 23 0 01-12.72-6.63c-1.15-1.27-3.39-4.58-3.25-4.82a9.34 9.34 0 011.15-.73L82 101l3.59-2.08.75 1.11a16.78 16.78 0 004.74 4.54c4 2.1 9.46 1.81 12.16-.62a5.43 5.43 0 00.69-6.92c-1-1.39-3-2.56-8.59-5-6.45-2.78-9.23-4.5-11.77-7.24a16.48 16.48 0 01-3.43-6.25 25 25 0 01-.22-8c1.33-6.23 6-10.58 12.82-11.87a31.66 31.66 0 019.49.26zm-29.34 5.24v5.12H56.66v46.23H45.15V69.26H28.88v-5a49.19 49.19 0 01.12-5.17C29.08 59 39 59 51 59h21.83z"></path></svg>' },
|
||||
'python': { name: 'Python', icon: '<svg viewBox="0 0 128 128"><linearGradient id="python-original-a" gradientUnits="userSpaceOnUse" x1="70.252" y1="1237.476" x2="170.659" y2="1151.089" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"><stop offset="0" stop-color="#5A9FD4"></stop><stop offset="1" stop-color="#306998"></stop></linearGradient><linearGradient id="python-original-b" gradientUnits="userSpaceOnUse" x1="209.474" y1="1098.811" x2="173.62" y2="1149.537" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"><stop offset="0" stop-color="#FFD43B"></stop><stop offset="1" stop-color="#FFE873"></stop></linearGradient><path fill="url(#python-original-a)" d="M63.391 1.988c-4.222.02-8.252.379-11.8 1.007-10.45 1.846-12.346 5.71-12.346 12.837v9.411h24.693v3.137H29.977c-7.176 0-13.46 4.313-15.426 12.521-2.268 9.405-2.368 15.275 0 25.096 1.755 7.311 5.947 12.519 13.124 12.519h8.491V67.234c0-8.151 7.051-15.34 15.426-15.34h24.665c6.866 0 12.346-5.654 12.346-12.548V15.833c0-6.693-5.646-11.72-12.346-12.837-4.244-.706-8.645-1.027-12.866-1.008zM50.037 9.557c2.55 0 4.634 2.117 4.634 4.721 0 2.593-2.083 4.69-4.634 4.69-2.56 0-4.633-2.097-4.633-4.69-.001-2.604 2.073-4.721 4.633-4.721z" transform="translate(0 10.26)"></path><path fill="url(#python-original-b)" d="M91.682 28.38v10.966c0 8.5-7.208 15.655-15.426 15.655H51.591c-6.756 0-12.346 5.783-12.346 12.549v23.515c0 6.691 5.818 10.628 12.346 12.547 7.816 2.297 15.312 2.713 24.665 0 6.216-1.801 12.346-5.423 12.346-12.547v-9.412H63.938v-3.138h37.012c7.176 0 9.852-5.005 12.348-12.519 2.578-7.735 2.467-15.174 0-25.096-1.774-7.145-5.161-12.521-12.348-12.521h-9.268zM77.809 87.927c2.561 0 4.634 2.097 4.634 4.692 0 2.602-2.074 4.719-4.634 4.719-2.55 0-4.633-2.117-4.633-4.719 0-2.595 2.083-4.692 4.633-4.692z" transform="translate(0 10.26)"></path><radialGradient id="python-original-c" cx="1825.678" cy="444.45" r="26.743" gradientTransform="matrix(0 -.24 -1.055 0 532.979 557.576)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#B8B8B8" stop-opacity=".498"></stop><stop offset="1" stop-color="#7F7F7F" stop-opacity="0"></stop></radialGradient><path opacity=".444" fill="url(#python-original-c)" d="M97.309 119.597c0 3.543-14.816 6.416-33.091 6.416-18.276 0-33.092-2.873-33.092-6.416 0-3.544 14.815-6.417 33.092-6.417 18.275 0 33.091 2.872 33.091 6.417z"></path></svg>' },
|
||||
'sh': { name: 'shell' }
|
||||
}
|
||||
%}
|
||||
|
||||
{% macro render(node) %}
|
||||
<div class="text-white text-sm md:text-base relative flex w-full {{ node.class }}">
|
||||
{% macro Language(node, example, isFirst) %}
|
||||
<details
|
||||
{{ 'open' if isFirst else '' }}
|
||||
class="group first:rounded-tl-md last:rounded-tr-md overflow-hidden"
|
||||
onclick="[...this.parentElement.children].forEach(c => (c.open = false))"
|
||||
>
|
||||
<summary
|
||||
class="
|
||||
flex gap-2 items-center px-4 py-2 cursor-pointer
|
||||
text-neutral-50 group-open:text-primary-500 bg-neutral-800 border-b-2 border-b-neutral-50/25 group-open:border-b-primary-600
|
||||
h-12 {{ node.summaryClass }}
|
||||
"
|
||||
>
|
||||
{% if languageMeta[example.language].icon %}
|
||||
<div class="w-[16px] h-[16px] hidden md:block">{{ languageMeta[example.language].icon | safe }}</div>
|
||||
{% endif %}
|
||||
{{ example.name or languageMeta[example.language].name }}
|
||||
</summary>
|
||||
<pre
|
||||
class="
|
||||
absolute top-12 left-0 right-0 w-full
|
||||
bg-neutral-900 text-neutral-50 p-4 rounded-bl-md rounded-br-md rounded-tr-md whitespace-pre-wrap text-sm
|
||||
overflow-x-none overflow-y-auto {{ node.preClass }}
|
||||
"
|
||||
onclick="event.preventDefault(); event.stopPropagation();"
|
||||
>{{ example.code | highlight(example.language) | safe }}</pre>
|
||||
</details>
|
||||
{% endmacro %}
|
||||
|
||||
{% set isFirst = true %}
|
||||
{% for example in node.examples %}
|
||||
{{ Language(node, example, true if isFirst else false) }}
|
||||
{% set isFirst = false %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
29
docs/renderer/nodes/Heading.njk
Normal file
29
docs/renderer/nodes/Heading.njk
Normal file
@@ -0,0 +1,29 @@
|
||||
{% set levelClasses = {
|
||||
'1': 'text-5xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600 mb-12',
|
||||
'2': 'text-4xl text-transparent bg-clip-text bg-gradient-to-b from-primary-400 to-primary-600 mb-12',
|
||||
'3': 'text-lg md:text-2xl font-light'
|
||||
} %}
|
||||
|
||||
{% set levelLinkClasses = {
|
||||
'1': 'border-transparent hover:border-primary-600',
|
||||
'2': 'border-transparent hover:border-primary-600',
|
||||
'3': 'border-transparent hover:border-current'
|
||||
} %}
|
||||
|
||||
{% macro render(node) %}
|
||||
<h{{ node.level }}
|
||||
id="{{ node.slug }}"
|
||||
{% if levelClasses[node.level] %}
|
||||
class="
|
||||
{{ levelClasses[node.level] }}
|
||||
{{ node.class }}
|
||||
"
|
||||
{% endif %}
|
||||
>
|
||||
{% if node.href %}
|
||||
<a href="{{ node.href }}" class="border-b-2 {{ levelLinkClasses[node.level] }}">{{ node.text | safe }}</a>
|
||||
{% else %}
|
||||
<a href="#{{ node.slug }}">{{ node.text | safe }}</a>
|
||||
{% endif %}
|
||||
</h{{ node.level }}>
|
||||
{% endmacro %}
|
||||
3
docs/renderer/nodes/Icon.njk
Normal file
3
docs/renderer/nodes/Icon.njk
Normal file
@@ -0,0 +1,3 @@
|
||||
{% macro render(node) %}
|
||||
{{ featherIcons(node.icon) }}
|
||||
{% endmacro %}
|
||||
7
docs/renderer/nodes/Include.njk
Normal file
7
docs/renderer/nodes/Include.njk
Normal file
@@ -0,0 +1,7 @@
|
||||
{% from "./Node.njk" import Node %}
|
||||
|
||||
{% macro render(node, page) %}
|
||||
{% for child in node.children %}
|
||||
{{ Node(child.type, child, page) }}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
13
docs/renderer/nodes/Logo.njk
Normal file
13
docs/renderer/nodes/Logo.njk
Normal file
@@ -0,0 +1,13 @@
|
||||
{% macro render(node) %}
|
||||
{% if node.variant == 'small' %}
|
||||
<div class="flex gap-2 items-center {{node.class}}">
|
||||
<img src="/public/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>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="flex gap-4 items-center {{node.class}}">
|
||||
<img src="/public/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>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
11
docs/renderer/nodes/Markdown.njk
Normal file
11
docs/renderer/nodes/Markdown.njk
Normal file
@@ -0,0 +1,11 @@
|
||||
{% macro render(node) %}
|
||||
<div class="
|
||||
prose text-base
|
||||
prose-p:mb-2 prose-ul:my-1 prose-ul:pl-0 prose-ul:ml-6
|
||||
md:prose-p:mb-4 md:prose-ul:pl-4 md:prose-ul:ml-2 md:prose-ul:my-2
|
||||
prose-li:my-0 text-current
|
||||
{{node.class}}
|
||||
">
|
||||
{{ node.text | safe }}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
48
docs/renderer/nodes/Navbar.njk
Normal file
48
docs/renderer/nodes/Navbar.njk
Normal file
@@ -0,0 +1,48 @@
|
||||
{% from "./Node.njk" import Node %}
|
||||
|
||||
{% 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>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render(node, ctx) %}
|
||||
<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">
|
||||
<a id="nav" class="peer" href="#nav" aria-hidden="true" tabindex="-1"></a>
|
||||
|
||||
<div class="absolute z-10 bg-neutral-800 w-full h-full top-0 left-0 lg:hidden"></div>
|
||||
|
||||
<a href="/" class="relative w-full z-20">
|
||||
{{ Node('Logo', { variant: 'small' }) }}
|
||||
</a>
|
||||
|
||||
<div class="
|
||||
group
|
||||
fixed flex flex-col gap-8 items-stretch w-full bg-neutral-800 text-neutral-50 top-20 bottom-0 left-0 px-7
|
||||
transition-transform
|
||||
-translate-y-full
|
||||
pointer-events-none
|
||||
peer-target:translate-y-0
|
||||
peer-target:pointer-events-auto
|
||||
lg:translate-y-0
|
||||
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
|
||||
">
|
||||
{{ navlink("/docs/javascript/", "Docs", ctx.url) }}
|
||||
{{ navlink("/examples/", "Examples", ctx.url) }}
|
||||
{{ navlink("/about/", "About", ctx.url) }}
|
||||
{{ navlink("/contribute/", "Contribute", ctx.url) }}
|
||||
<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">
|
||||
{{ Node('Icon', { icon: 'github' }) }}<div class="ml-4 lg:hidden">Code</div>
|
||||
</a>
|
||||
</div>
|
||||
<a href="#nav" title="Open Menu" class="absolute right-4 flex peer-target:hidden lg:hidden h-16 w-16 items-center justify-center z-20">
|
||||
{{ Node('Icon', { icon: 'menu' }) }}
|
||||
</a>
|
||||
|
||||
<a href="#" title="Close Menu" class="absolute right-4 hidden peer-target:flex lg:hidden lg:peer-target:hidden h-16 w-16 items-center justify-center text-primary-500 z-20">
|
||||
{{ Node('Icon', { icon: 'x' }) }}
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
{% endmacro %}
|
||||
4
docs/renderer/nodes/Node.njk
Normal file
4
docs/renderer/nodes/Node.njk
Normal file
@@ -0,0 +1,4 @@
|
||||
{% macro Node(name, params, ctx) %}
|
||||
{% from "./" + name + ".njk" import render %}
|
||||
{{ render(params, ctx) }}
|
||||
{% endmacro %}
|
||||
8
docs/renderer/nodes/SearchBox.njk
Normal file
8
docs/renderer/nodes/SearchBox.njk
Normal file
@@ -0,0 +1,8 @@
|
||||
{% from "./Node.njk" import Node %}
|
||||
|
||||
{% macro render(node) %}
|
||||
<div class="flex gap-4 px-4 py-2 rounded-md border-2 border-neutral-50/75 focus-within:border-primary-400 focus-within:text-primary-400 bg-transparent text-neutral-50 {{ node.class }}">
|
||||
<input type="text" placeholder="Search" class="w-full bg-transparent outline-none"/>
|
||||
{{ Node('Icon', { icon: 'search' }) }}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
20
docs/renderer/nodes/Section.njk
Normal file
20
docs/renderer/nodes/Section.njk
Normal file
@@ -0,0 +1,20 @@
|
||||
{% from "./Node.njk" import Node %}
|
||||
|
||||
{% set variants = {
|
||||
light: "bg-gradient-to-b from-neutral-50 to-neutral-50/50 text-neutral-900",
|
||||
dark: "bg-gradient-to-b from-neutral-800 to-neutral-900 text-neutral-50"
|
||||
}
|
||||
%}
|
||||
|
||||
{% 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">
|
||||
<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="group/{{node.variant}} {{ variants[node.variant] }}">
|
||||
<div class="{{ node.class }} container mx-auto px-8 pt-16 pb-48">
|
||||
{% for child in node.children %}
|
||||
{{ Node(child.type, child, ctx) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endmacro %}
|
||||
19
docs/renderer/nodes/TableOfContents.njk
Normal file
19
docs/renderer/nodes/TableOfContents.njk
Normal 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 %}
|
||||
50
docs/renderer/render.js
Normal file
50
docs/renderer/render.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import nunjucks from 'nunjucks'
|
||||
import HighlightJS from 'highlight.js'
|
||||
import readPage from '../read-page/index.js'
|
||||
import googleFonts from './util/google-fonts.js'
|
||||
import featherIcons from './util/feather-icons.js'
|
||||
|
||||
const pages = {
|
||||
'/': './pages/index.tce',
|
||||
'/about/': './pages/about.tce'
|
||||
}
|
||||
|
||||
async function render() {
|
||||
// await fs.rm('dist', { recursive: true })
|
||||
|
||||
for (const [urlPath, filePath] of Object.entries(pages)) {
|
||||
const env = nunjucks.configure('renderer/', { autoescape: false })
|
||||
|
||||
env.addGlobal('googleFonts', googleFonts)
|
||||
env.addGlobal('featherIcons', featherIcons)
|
||||
|
||||
HighlightJS.registerLanguage('terrace', () => ({
|
||||
name: 'Terrace',
|
||||
contains: [
|
||||
{
|
||||
className: 'keyword',
|
||||
begin: /^\s*(.*?)(?:\s|$)/,
|
||||
relevance: 1
|
||||
}
|
||||
]
|
||||
}))
|
||||
|
||||
env.addFilter("highlight", (value, language) => {
|
||||
return HighlightJS.highlight(value, { language }).value
|
||||
})
|
||||
|
||||
const page = await readPage(filePath)
|
||||
const result = env.render('layout.njk', { page, url: urlPath, file: filePath })
|
||||
|
||||
await fs.mkdir(path.join('dist', urlPath), { recursive: true })
|
||||
await fs.writeFile(path.join('dist', urlPath, 'index.html'), result)
|
||||
}
|
||||
|
||||
// await fs.cp('node_modules/highlight.js/styles/atom-one-dark.css', '');
|
||||
await fs.cp('./public/', './dist/public/', { recursive: true })
|
||||
await fs.cp('./favicon.ico', './dist/favicon.ico', { recursive: true })
|
||||
}
|
||||
|
||||
render()
|
||||
19
docs/renderer/util/feather-icons.js
Normal file
19
docs/renderer/util/feather-icons.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import feather from 'feather-icons'
|
||||
|
||||
const defaultAttributes = {
|
||||
"class": "feather feather-x",
|
||||
"xmlns": "http://www.w3.org/2000/svg",
|
||||
"width": 24,
|
||||
"height": 24,
|
||||
"viewBox": "0 0 24 24",
|
||||
"fill": "none",
|
||||
"stroke": "currentColor",
|
||||
"stroke-width": 2,
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
}
|
||||
|
||||
export default (iconName, attributes = {}) => {
|
||||
attributes = { ...defaultAttributes, ...attributes }
|
||||
return feather.icons[iconName].toSvg(attributes)
|
||||
}
|
||||
45
docs/renderer/util/google-fonts.js
Normal file
45
docs/renderer/util/google-fonts.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import https from 'node:https'
|
||||
|
||||
const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
|
||||
|
||||
const isValidURL = url => {
|
||||
return /fonts.googleapis.com/.test(url)
|
||||
}
|
||||
|
||||
const downloadFont = url => {
|
||||
return new Promise((resolve) => {
|
||||
let rawData = ''
|
||||
https.get(
|
||||
url,
|
||||
{
|
||||
headers: {
|
||||
'user-agent': UA,
|
||||
},
|
||||
},
|
||||
res => {
|
||||
res.on('data', chunk => {
|
||||
rawData += chunk
|
||||
})
|
||||
res.on('end', () => {
|
||||
resolve(rawData.toString('utf8'))
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const createInlineCss = async url => {
|
||||
if (!isValidURL(url)) {
|
||||
throw new Error('Invalid Google Fonts URL')
|
||||
}
|
||||
|
||||
const content = await downloadFont(url)
|
||||
|
||||
return (
|
||||
`<link rel="preconnect" href="https://fonts.gstatic.com">`+
|
||||
`<link data-href="${url}" rel="stylesheet">`+
|
||||
`<style data-href='${url}'>${content}</style>`
|
||||
)
|
||||
}
|
||||
|
||||
export default createInlineCss
|
||||
Reference in New Issue
Block a user