Compare commits
3 Commits
3070cc92f7
...
42b724966d
Author | SHA1 | Date | |
---|---|---|---|
42b724966d | |||
db5ebbb807 | |||
0fd81d31e3 |
28
.gitignore
vendored
28
.gitignore
vendored
@ -1,4 +1,24 @@
|
||||
node_modules
|
||||
static/css/out.css
|
||||
static/learn
|
||||
static/js/highlighter.js
|
||||
# build output
|
||||
dist/
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
|
||||
# jetbrains setting folder
|
||||
.idea/
|
||||
|
@ -9,23 +9,14 @@ pipeline {
|
||||
sh 'bun i'
|
||||
}
|
||||
}
|
||||
stage('Build tailwind') {
|
||||
environment {
|
||||
PATH = "${env.WORKSPACE}/node_modules/.bin:${env.PATH}"
|
||||
}
|
||||
steps {
|
||||
sh 'md-docs'
|
||||
sh './node_modules/.bin/tailwindcss -i ./tailwind.css -o ./static/css/out.css --minify'
|
||||
}
|
||||
}
|
||||
stage('Build bundle') {
|
||||
steps {
|
||||
sh 'bun bundle'
|
||||
sh 'bun run build'
|
||||
}
|
||||
}
|
||||
stage('Deploy') {
|
||||
steps {
|
||||
sh 'cp -r ./static/* /var/www/thp-docs/'
|
||||
sh 'cp -r ./dist/* /var/www/thp-docs/'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
47
README.md
Normal file
47
README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Astro Starter Kit: Minimal
|
||||
|
||||
```sh
|
||||
npm create astro@latest -- --template minimal
|
||||
```
|
||||
|
||||
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal)
|
||||
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/minimal)
|
||||
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/minimal/devcontainer.json)
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```text
|
||||
/
|
||||
├── public/
|
||||
├── src/
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
└── package.json
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
12
astro.config.mjs
Normal file
12
astro.config.mjs
Normal file
@ -0,0 +1,12 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
import tailwind from "@astrojs/tailwind";
|
||||
|
||||
import mdx from "@astrojs/mdx";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [tailwind(), mdx()],
|
||||
markdown: {
|
||||
syntaxHighlight: false,
|
||||
},
|
||||
});
|
@ -1,11 +0,0 @@
|
||||
input: md
|
||||
output: static
|
||||
template: static/template.html
|
||||
|
||||
headings:
|
||||
h1: text-4xl mb-4 mt-8 font-display opacity-90 font-black text-c-text-2
|
||||
h2: text-2xl mt-10 mb-4 font-display opacity-90 font-bold text-c-text-2
|
||||
h3: text-xl mt-10 mb-4 font-display opacity-90 text-c-text-2
|
||||
|
||||
file_tree_title_classes: "uppercase font-display text-c-text-2 font-medium"
|
||||
link_classes: text-blue-500 hover:underline
|
@ -1,5 +0,0 @@
|
||||
# Operators
|
||||
|
||||
Some common operators
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
# Blocks
|
||||
|
||||
Blocks :D
|
||||
|
@ -1,72 +0,0 @@
|
||||
path: ""
|
||||
name: ""
|
||||
has_index: true
|
||||
children:
|
||||
- path: index
|
||||
name: Index
|
||||
- path: install
|
||||
name: Install
|
||||
- path: basics
|
||||
name: Basics
|
||||
children:
|
||||
- path: hello-world
|
||||
name: Hello, world!
|
||||
- name: Variables
|
||||
path: variables
|
||||
- path: datatypes
|
||||
name: Datatypes
|
||||
- path: comments
|
||||
name: Comments
|
||||
- name: Flow control
|
||||
path: flow-control
|
||||
children:
|
||||
- name: Blocks
|
||||
path: blocks
|
||||
- name: Conditionals
|
||||
path: conditionals
|
||||
- name: Loops
|
||||
path: loops
|
||||
- name: Match
|
||||
path: match
|
||||
- name: Data structures
|
||||
path: data-structures
|
||||
children:
|
||||
- name: Tuples
|
||||
path: tuples
|
||||
- name: Arrays
|
||||
path: arrays
|
||||
- name: Maps
|
||||
path: maps
|
||||
- name: Enums
|
||||
path: enums
|
||||
- name: Functions
|
||||
path: functions
|
||||
children:
|
||||
- name: Declaration
|
||||
path: declaration
|
||||
- name: Parameter references
|
||||
path: parameters
|
||||
- name: Higher-order functions
|
||||
path: higher-order
|
||||
- name: Lambdas
|
||||
path: lambdas
|
||||
- name: Error handling
|
||||
path: error-handling
|
||||
children:
|
||||
- name: Nullable types
|
||||
path: "null"
|
||||
- name: Try expressions
|
||||
path: try
|
||||
- name: Classes
|
||||
path: classes
|
||||
children:
|
||||
- name: Definition
|
||||
path: definition
|
||||
- name: Static
|
||||
path: static
|
||||
- name: Interfaces
|
||||
path: interfaces
|
||||
- name: Anonymous classes
|
||||
path: anonymous
|
||||
- name: Magic
|
||||
path: magic
|
37
package.json
37
package.json
@ -1,29 +1,22 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"name": "thp-docs",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"generate": "md-docs",
|
||||
"bundle": "bun build ./lexer/highlighter.ts --outdir ./static/js/ --format esm --minify",
|
||||
"dev": "concurrently -k \"tailwindcss -i ./tailwind.css -o ./static/css/out.css --watch\" \"serve ./static/ -l 3333\"",
|
||||
"tailwind:watch": "tailwindcss -i ./tailwind.css -o ./static/css/out.css --watch",
|
||||
"tailwind:build": "tailwindcss -i ./tailwind.css -o ./static/css/out.css"
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/bun": "^1.0.10",
|
||||
"@astrojs/check": "^0.5.10",
|
||||
"@astrojs/mdx": "^2.3.0",
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@types/bun": "^1.0.12",
|
||||
"astro": "^4.6.1",
|
||||
"codejar": "^4.2.0",
|
||||
"tailwindcss": "^3.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^8.2.0",
|
||||
"serve": "^14.2.1",
|
||||
"bun-types": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^5.4.5"
|
||||
}
|
||||
}
|
@ -1,6 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--c-bg: #121212;
|
39
public/css/pages.css
Normal file
39
public/css/pages.css
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 2.25rem;
|
||||
line-height: 2.5rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 2rem;
|
||||
font-family: Inter, sans-serif;
|
||||
opacity: 0.9;
|
||||
font-weight: 900;
|
||||
color: var(--c-text-2);
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
/* use these tailwind classes: text-2xl mt-10 mb-4 font-display opacity-90 font-bold text-c-text-2 */
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 2.5rem;
|
||||
font-family: Inter, sans-serif;
|
||||
opacity: 0.9;
|
||||
font-weight: 700;
|
||||
color: var(--c-text-2);
|
||||
}
|
||||
|
||||
.markdown ul {
|
||||
list-style-type: disc;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
.markdown ul li {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.markdown pre {
|
||||
margin: 0.5em 0;
|
||||
padding: 0.75em 0.75em;
|
||||
color: var(--code-theme-color);
|
||||
background: var(--code-theme-bg-color);
|
||||
}
|
9
public/favicon.svg
Normal file
9
public/favicon.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||
<style>
|
||||
path { fill: #000; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #FFF; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
After Width: | Height: | Size: 749 B |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
19
src/components/Navbar.astro
Normal file
19
src/components/Navbar.astro
Normal file
@ -0,0 +1,19 @@
|
||||
<nav class="fixed w-full top-0 h-12 border-b border-[rgba(150,150,150,0.25)] bg-c-nav-bg backdrop-blur-md z-20">
|
||||
<div class="container mx-auto h-full w-full flex items-center">
|
||||
<a href="/" class="inline-block px-4 font-display font-black text-2xl hover:underline">
|
||||
<span class="text-[#F5A9B8]">t</span><span>h</span><span class="text-[#5BCEFA]">p</span>
|
||||
</a>
|
||||
<a href="/learn/" class="hidden lg:inline-block px-4 font-display font-bold-text-xl hover:underline">
|
||||
Learn
|
||||
</a>
|
||||
<a href="/how-to/" class="hidden lg:inline-block px-4 font-display font-bold-text-xl hover:underline">
|
||||
How to guides
|
||||
</a>
|
||||
<a href="/reference/" class="hidden lg:inline-block px-4 font-display font-bold-text-xl hover:underline">
|
||||
Language reference
|
||||
</a>
|
||||
<a href="/api/" class="hidden lg:inline-block px-4 font-display font-bold-text-xl hover:underline">
|
||||
Stdlib API
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
39
src/components/Sidebar.astro
Normal file
39
src/components/Sidebar.astro
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
import type { PageEntry } from "../layouts/PagesLayout.astro";
|
||||
|
||||
const entry: PageEntry = Astro.props.entry;
|
||||
const basePath: string = Astro.props.basePath;
|
||||
|
||||
const entryPath = entry.path === "index"? "": entry.path;
|
||||
---
|
||||
|
||||
{
|
||||
!entry.children && (
|
||||
<li>
|
||||
<a
|
||||
class="inline-block rounded-2xl w-full hover:bg-neutral-200 dark:hover:bg-neutral-800 transition-colors px-3 py-2"
|
||||
href={`${basePath}${entryPath}`}
|
||||
>
|
||||
{entry.title}
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
{
|
||||
entry.children && (
|
||||
<>
|
||||
<div class="mt-6 px-3 py-1 uppercase font-display text-c-text-2 font-medium">
|
||||
{entry.title}
|
||||
</div>
|
||||
|
||||
<ul class="my-1">
|
||||
{entry.children!.map((nextEntry) => (
|
||||
<Astro.self
|
||||
entry={nextEntry}
|
||||
basePath={`${basePath}${entry.path}/`}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
)
|
||||
}
|
39
src/components/TOC.astro
Normal file
39
src/components/TOC.astro
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
// github.com/rezahedi/rezahedi.dev/blob/main/src/components/TOC.astro
|
||||
import TOCHeading from "./TOCHeading.astro";
|
||||
|
||||
const { headings } = Astro.props;
|
||||
|
||||
const toc = buildHierarchy(headings);
|
||||
|
||||
function buildHierarchy(headings: any) {
|
||||
const toc: any[] = [];
|
||||
const parentHeadings = new Map();
|
||||
|
||||
if (!headings) return toc;
|
||||
|
||||
headings.forEach((h: any) => {
|
||||
const heading = { ...h, subheadings: [] };
|
||||
parentHeadings.set(heading.depth, heading);
|
||||
// Change 2 to 1 if your markdown includes your <h1>
|
||||
if (heading.depth === 1) {
|
||||
toc.push(heading);
|
||||
} else {
|
||||
parentHeadings.get(heading.depth - 1).subheadings.push(heading);
|
||||
}
|
||||
});
|
||||
return toc;
|
||||
}
|
||||
---
|
||||
|
||||
{
|
||||
toc && toc.length > 0 && (
|
||||
<nav class="article-toc">
|
||||
<ul>
|
||||
{toc.map((heading) => (
|
||||
<TOCHeading heading={heading} />
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
19
src/components/TOCHeading.astro
Normal file
19
src/components/TOCHeading.astro
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
// github.com/rezahedi/rezahedi.dev/blob/main/src/components/TOCHeading.astro
|
||||
const { heading } = Astro.props;
|
||||
---
|
||||
|
||||
<li>
|
||||
<a class="inline-block py-1" href={"#" + heading.slug}>
|
||||
{heading.text}
|
||||
</a>
|
||||
{
|
||||
heading.subheadings.length > 0 && (
|
||||
<ul class="px-2">
|
||||
{heading.subheadings.map((subheading: any) => (
|
||||
<Astro.self heading={subheading} />
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
</li>
|
1
src/env.d.ts
vendored
Normal file
1
src/env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="astro/client" />
|
31
src/layouts/BaseLayout.astro
Normal file
31
src/layouts/BaseLayout.astro
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
const {title} = Astro.props;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{title ?? "THP: Typed Hypertext Processor"}</title>
|
||||
|
||||
<link rel="stylesheet" href="/css/global.css" />
|
||||
<link rel="stylesheet" href="/css/pages.css">
|
||||
<link rel="stylesheet" href="/css/xcode-colors.css" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500;600;700;800;900&family=Fira+Code&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<body class="bg-c-bg text-c-text">
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
146
src/layouts/PagesLayout.astro
Normal file
146
src/layouts/PagesLayout.astro
Normal file
@ -0,0 +1,146 @@
|
||||
---
|
||||
import Navbar from "../components/Navbar.astro";
|
||||
import BaseLayout from "./BaseLayout.astro";
|
||||
import TOC from "../components/TOC.astro";
|
||||
import Sidebar from "../components/Sidebar.astro";
|
||||
|
||||
const { frontmatter, headings } = Astro.props;
|
||||
|
||||
const posts = await Astro.glob("../pages/learn/**/*.md");
|
||||
|
||||
// The index.md page must have a `pagesLayout` frontmatter, which declares the order of all the pages.
|
||||
const indexSubpath = `/learn/index.md`;
|
||||
|
||||
const indexPage = posts.find((post) => post.file.endsWith(indexSubpath));
|
||||
|
||||
if (indexPage === undefined) {
|
||||
throw new Error(`No index page found at ${indexSubpath}`);
|
||||
}
|
||||
|
||||
export type PageEntry = {
|
||||
path: string;
|
||||
title?: string;
|
||||
children?: Array<PageEntry>;
|
||||
};
|
||||
|
||||
const pagesIndex: Array<PageEntry> | undefined =
|
||||
indexPage.frontmatter.pagesLayout;
|
||||
|
||||
if (pagesIndex === undefined) {
|
||||
console.error(indexPage.frontmatter);
|
||||
throw new Error(`No pagesLayout frontmatter found in ${indexSubpath}`);
|
||||
}
|
||||
|
||||
function validateEntry(entry: PageEntry, basePath: string) {
|
||||
if (!entry.children) {
|
||||
// Attempt to get the page title from frontmatter
|
||||
const pageData = posts.find((post) =>
|
||||
post.file.endsWith(entry.path + ".md"),
|
||||
);
|
||||
|
||||
if (pageData === undefined) {
|
||||
console.error(entry);
|
||||
console.error(entry.path + ".md");
|
||||
throw new Error(`No page found at ${entry.path}`);
|
||||
}
|
||||
|
||||
// set the title
|
||||
entry.title = pageData.frontmatter.title ?? "Title not set";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Recursively search for children
|
||||
if (!entry.title) {
|
||||
console.log(entry);
|
||||
throw new Error(
|
||||
`No title found in ${basePath + entry.path}, which is a folder and requires it.`,
|
||||
);
|
||||
}
|
||||
|
||||
const folderName = entry.title;
|
||||
|
||||
entry.children.forEach((child) =>
|
||||
validateEntry(child, basePath + "/" + folderName),
|
||||
);
|
||||
}
|
||||
|
||||
for (const entry of pagesIndex) {
|
||||
validateEntry(entry, `/learn/`);
|
||||
}
|
||||
---
|
||||
|
||||
<BaseLayout title={frontmatter.title}>
|
||||
<Navbar />
|
||||
|
||||
<div class="lg:grid lg:grid-cols-[14rem_auto_12rem] container mx-auto">
|
||||
<div class="pt-12 lg:h-screen lg:sticky top-0">
|
||||
<nav
|
||||
id="sidebar"
|
||||
class="py-4 pr-2 overflow-x-scroll lg:h-[calc(100vh-3rem)]"
|
||||
>
|
||||
{
|
||||
pagesIndex.map((entry) => (
|
||||
<Sidebar entry={entry} basePath="/learn/" />
|
||||
))
|
||||
}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<main class="lg:py-[3.5rem] lg:pl-12 lg:pr-4 markdown min-w-0">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<div class="lg:pt-12 pt-4 max-h-screen overflow-x-scroll sticky top-0">
|
||||
<nav class="rounded-md lg:mt-10">
|
||||
<h2 class="font-display font-medium pb-2 text-c-text-2">
|
||||
On this page
|
||||
</h2>
|
||||
|
||||
<TOC headings={headings} />
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import { thp_highlighter, CodeJar } from "../lexer/highlighter";
|
||||
// Add an editor to all code samples
|
||||
|
||||
const code_elements = document.querySelectorAll(".language-thp");
|
||||
|
||||
for (const e of [...code_elements]) {
|
||||
const el = e as HTMLElement;
|
||||
const pre_parent = el.parentElement!;
|
||||
const new_div = document.createElement("div");
|
||||
const code = el.innerText;
|
||||
|
||||
el.parentElement!.className = "language-thp";
|
||||
pre_parent.removeChild(el);
|
||||
pre_parent.appendChild(new_div);
|
||||
|
||||
CodeJar(new_div, thp_highlighter, {
|
||||
tab: " ",
|
||||
}).updateCode(code);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
// Highlight the current url of the sidebar
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
let current_uri = window.location.pathname;
|
||||
|
||||
const sidebar = document.getElementById("sidebar")!;
|
||||
const links = sidebar.querySelectorAll("a");
|
||||
for (const link of [...links]) {
|
||||
if (link.getAttribute("href") === current_uri) {
|
||||
console.log(sidebar.offsetTop);
|
||||
console.log(link.offsetTop);
|
||||
|
||||
sidebar.scrollTop = link.offsetTop - sidebar.offsetTop - 250;
|
||||
|
||||
link.classList.add("bg-pink-200", "dark:bg-pink-950");
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</BaseLayout>
|
@ -1,7 +1,7 @@
|
||||
import {lex} from "./lexer.ts";
|
||||
import { CodeJar } from "codejar"
|
||||
import { lex } from "./lexer";
|
||||
import {CodeJar as Codejar} from "codejar";
|
||||
|
||||
function thp_highlighter(editor: any) {
|
||||
export function thp_highlighter(editor: any) {
|
||||
let code: string = editor.textContent;
|
||||
|
||||
let tokens = lex(code);
|
||||
@ -15,7 +15,4 @@ function thp_highlighter(editor: any) {
|
||||
editor.innerHTML = highlighted_code;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
window.thp_highlighter = thp_highlighter;
|
||||
// @ts-ignore
|
||||
window.CodeJar = CodeJar;
|
||||
export const CodeJar = Codejar;
|
@ -1,5 +1,5 @@
|
||||
import type { Token } from "./lexer.ts";
|
||||
import { is_identifier_char } from "./utils.ts";
|
||||
import type { Token } from "./lexer";
|
||||
import { is_identifier_char } from "./utils";
|
||||
|
||||
/**
|
||||
* Scans an identifier, at the given position in the input string.
|
@ -1,7 +1,7 @@
|
||||
import { scan_identifier } from "./identifier_lexer.ts";
|
||||
import { scan_number } from "./number_lexer.ts";
|
||||
import { scan_string } from "./string_lexer.ts";
|
||||
import { is_digit, is_lowercase, is_uppercase } from "./utils.ts";
|
||||
import { scan_identifier } from "./identifier_lexer";
|
||||
import { scan_number } from "./number_lexer";
|
||||
import { scan_string } from "./string_lexer";
|
||||
import { is_digit, is_lowercase, is_uppercase } from "./utils";
|
||||
|
||||
export type Token = {
|
||||
v: string,
|
@ -1,5 +1,5 @@
|
||||
import type { Token } from "./lexer.ts";
|
||||
import { is_digit } from "./utils.ts";
|
||||
import type { Token } from "./lexer";
|
||||
import { is_digit } from "./utils";
|
||||
|
||||
/**
|
||||
* Scans a number, at the given position in the input string.
|
@ -1,4 +1,4 @@
|
||||
import type { Token } from "./lexer.ts";
|
||||
import type { Token } from "./lexer";
|
||||
|
||||
export function scan_string(input: string, starting_position: number): [Token, number] {
|
||||
let value = "\"";
|
125
src/pages/index.astro
Normal file
125
src/pages/index.astro
Normal file
@ -0,0 +1,125 @@
|
||||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
import Navbar from "../components/Navbar.astro";
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
<Navbar />
|
||||
|
||||
<div
|
||||
class="container mx-auto lg:py-16 py-2 lg:grid 2xl:grid-cols-[auto_32rem] lg:grid-cols-[auto_36rem] gap-4 lg:px-10 px-2"
|
||||
>
|
||||
<div class="lg:pl-10 table">
|
||||
<div class="table-cell align-middle">
|
||||
<h1
|
||||
class="font-display font-bold text-c-text-2 lg:text-5xl text-3xl lg:text-left text-center leading-tight"
|
||||
>
|
||||
A modern, type safe,
|
||||
<br class="hidden lg:inline-block" />
|
||||
secure language
|
||||
<br class="hidden lg:inline-block" />
|
||||
compiled to PHP
|
||||
</h1>
|
||||
<p class="font-display text-c-text text-xl pt-6 lg:pr-12">
|
||||
Inspired by Rust, Zig and Swift, THP has a modern syntax,
|
||||
semantics, type system and stdlib.
|
||||
</p>
|
||||
<br />
|
||||
<br />
|
||||
<div class="text-center">
|
||||
<a
|
||||
class="inline-block font-display text-lg rounded-full border-2 border-pink-400 py-2 px-8
|
||||
transition-colors hover:text-black hover:bg-pink-400"
|
||||
href="/learn/"
|
||||
>
|
||||
Tutorial
|
||||
</a>
|
||||
|
||||
<a
|
||||
class="inline-block font-display text-lg border-2 border-sky-400 py-2 px-8 mx-6 rounded-full
|
||||
transition-colors hover:text-black hover:bg-sky-400"
|
||||
href="/install/"
|
||||
>
|
||||
Install
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-[var(--code-theme-bg-color)] lg:p-6 p-2 rounded-lg relative"
|
||||
>
|
||||
<span
|
||||
class="absolute lg:inline-block hidden h-[35rem] w-[35rem] -z-10 top-1/2 left-1/2 rounded-full
|
||||
transform -translate-x-1/2 -translate-y-1/2"
|
||||
style="background-image: conic-gradient(from 180deg at 50% 50%,#5BCEFA 0deg,#a853ba 180deg,#F5A9B8 1turn);
|
||||
filter: blur(75px); opacity: 0.75;"
|
||||
>
|
||||
</span>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="54"
|
||||
height="14"
|
||||
viewBox="0 0 54 14"
|
||||
>
|
||||
<g fill="none" fill-rule="evenodd" transform="translate(1 1)">
|
||||
<circle
|
||||
cx="6"
|
||||
cy="6"
|
||||
r="6"
|
||||
fill="#FF5F56"
|
||||
stroke="#E0443E"
|
||||
stroke-width=".5"></circle>
|
||||
<circle
|
||||
cx="26"
|
||||
cy="6"
|
||||
r="6"
|
||||
fill="#FFBD2E"
|
||||
stroke="#DEA123"
|
||||
stroke-width=".5"></circle>
|
||||
<circle
|
||||
cx="46"
|
||||
cy="6"
|
||||
r="6"
|
||||
fill="#27C93F"
|
||||
stroke="#1AAB29"
|
||||
stroke-width=".5"></circle>
|
||||
</g>
|
||||
</svg>
|
||||
<div class="h-1"></div>
|
||||
<div id="editor" class="font-mono language-thp"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import { thp_highlighter, CodeJar } from "../lexer/highlighter";
|
||||
|
||||
let jar = CodeJar(document.getElementById("editor")!, thp_highlighter, {
|
||||
tab: " ",
|
||||
});
|
||||
|
||||
jar.updateCode(
|
||||
`// Actual generics & sum types
|
||||
fun find_person(Int person_id) -> Result[String, String] {
|
||||
// Easy, explicit error bubbling
|
||||
try Person::find_by_id(person_id)
|
||||
}
|
||||
|
||||
val id = POST::get("person_id") ?? exit("Null person_id")
|
||||
// Errors as values
|
||||
val person = try find_person(person_id: id) with error {
|
||||
eprint("Error: {error}")
|
||||
exit("Person not found")
|
||||
}
|
||||
|
||||
// First class HTML-like templates & components
|
||||
print(
|
||||
<a href="/person/reports/{person.id}">
|
||||
welcome, {person.name}
|
||||
</a>
|
||||
)
|
||||
// And more!`,
|
||||
);
|
||||
</script>
|
||||
</BaseLayout>
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Comments
|
||||
---
|
||||
|
||||
# Comments
|
||||
|
||||
Only these two:
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Datatypes
|
||||
---
|
||||
|
||||
# Datatypes
|
||||
|
||||
Datatypes's first character are always uppercase.
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Hello world
|
||||
---
|
||||
|
||||
# Hello, world!
|
||||
|
||||
Create a file named `hello.thp` with the contents:
|
10
src/pages/learn/basics/operators.md
Normal file
10
src/pages/learn/basics/operators.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Install
|
||||
---
|
||||
|
||||
# Operators
|
||||
|
||||
Some common operators
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Variables
|
||||
|
||||
---
|
||||
|
||||
# Variables
|
||||
|
||||
thp distinguishes between mutable and immutable variables.
|
@ -1,3 +1,7 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Anonymous classes
|
||||
---
|
||||
# Anonymous classes
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Classes
|
||||
---
|
||||
|
||||
# Classes
|
||||
|
||||
Basically kotlin syntax.
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Interfaces
|
||||
---
|
||||
|
||||
# Interfaces
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Magic methods
|
||||
---
|
||||
|
||||
# Magic methods
|
||||
|
||||
Don't get special treatment.
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Static
|
||||
---
|
||||
|
||||
# Static in classes
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Arrays
|
||||
---
|
||||
|
||||
# Arrays
|
||||
|
||||
Use square brackets as usual.
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Enums
|
||||
---
|
||||
|
||||
# Enums (Tagged unions)
|
||||
|
||||
## Basic enums
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Maps
|
||||
---
|
||||
|
||||
# Maps
|
||||
|
||||
Also known as Associative Arrays, or Objects in other languages.
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Tuples
|
||||
---
|
||||
|
||||
# Tuples
|
||||
|
||||
Uses `#()` just to avoid confusion with function calls and grouping (`()`).
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Nullable types
|
||||
---
|
||||
|
||||
# Nullable types
|
||||
|
||||
All datatypes in THP disallow the usage of `null` by default.
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Try expressions
|
||||
---
|
||||
|
||||
# Try expressions
|
||||
|
||||
```thp
|
9
src/pages/learn/flow-control/blocks.md
Normal file
9
src/pages/learn/flow-control/blocks.md
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Blocks
|
||||
---
|
||||
|
||||
# Blocks
|
||||
|
||||
Blocks :D
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Conditionals
|
||||
---
|
||||
|
||||
# Conditionals
|
||||
|
||||
- Only `Bool` are accepted. No truthy/falsy.
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Loops
|
||||
---
|
||||
|
||||
# Loops
|
||||
|
||||
## For loop
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Match
|
||||
---
|
||||
|
||||
# Match
|
||||
|
||||
## Syntax
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Declaration
|
||||
---
|
||||
|
||||
# Declaration
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Higher Order Functions
|
||||
---
|
||||
|
||||
# Higher Order functions
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Lambdas
|
||||
---
|
||||
|
||||
# Lambdas / Anonymous functions
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../../layouts/PagesLayout.astro
|
||||
title: Function parameters
|
||||
---
|
||||
|
||||
# Function parameters
|
||||
|
||||
|
@ -1,3 +1,53 @@
|
||||
---
|
||||
layout: ../../layouts/PagesLayout.astro
|
||||
title: Welcome
|
||||
pagesLayout:
|
||||
- path: index
|
||||
- path: install
|
||||
- path: basics
|
||||
title: Basics
|
||||
children:
|
||||
- path: hello-world
|
||||
- path: variables
|
||||
- path: datatypes
|
||||
- path: comments
|
||||
- path: flow-control
|
||||
title: Flow control
|
||||
children:
|
||||
- path: blocks
|
||||
- path: conditionals
|
||||
- path: loops
|
||||
- path: match
|
||||
- path: data-structures
|
||||
title: Data structures
|
||||
children:
|
||||
- path: tuples
|
||||
- path: arrays
|
||||
- path: maps
|
||||
- path: enums
|
||||
- path: functions
|
||||
title: Functions
|
||||
children:
|
||||
- path: declaration
|
||||
- path: parameters
|
||||
- path: higher-order
|
||||
- path: lambdas
|
||||
- path: error-handling
|
||||
title: Error handling
|
||||
children:
|
||||
- path: "null"
|
||||
- path: try
|
||||
- path: classes
|
||||
title: Classes
|
||||
children:
|
||||
- path: definition
|
||||
- path: static
|
||||
- path: interfaces
|
||||
- path: anonymous
|
||||
- path: magic
|
||||
|
||||
---
|
||||
|
||||
# Welcome
|
||||
|
||||
Welcome to the documentation of the THP programming languague.
|
||||
@ -9,7 +59,7 @@ THP is a new programming language that compiles to PHP.
|
||||
<br>
|
||||
|
||||
This page discusses some of the design decitions of the language,
|
||||
if you want to install THP go to the [installation guide](/installation-guide)
|
||||
if you want to install THP go to the [installation guide](install)
|
||||
|
||||
If you want to learn the language, go to the learn section.
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
layout: ../../layouts/PagesLayout.astro
|
||||
title: Install
|
||||
---
|
||||
|
||||
# Install
|
||||
|
||||
## From scratch
|
@ -1,122 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>THP: Typed Hypertext Processor</title>
|
||||
|
||||
<!-- Tailwind output -->
|
||||
<link href="/css/out.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/css/xcode-colors.css">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500;600;700;800;900&family=Fira+Code&display=swap"
|
||||
rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body class="bg-c-bg text-c-text">
|
||||
<nav class="sticky top-0 h-12 border-b border-[rgba(150,150,150,0.25)] bg-c-nav-bg backdrop-blur-md z-20">
|
||||
<div class="container mx-auto h-full w-full flex items-center">
|
||||
<a href="/" class="inline-block px-4 font-display font-black text-2xl hover:underline">
|
||||
<span class="text-[#F5A9B8]">t</span><span>h</span><span class="text-[#5BCEFA]">p</span>
|
||||
</a>
|
||||
<a href="/learn/" class="hidden lg:inline-block px-4 font-display font-bold-text-xl hover:underline">
|
||||
Learn
|
||||
</a>
|
||||
<a href="/how-to/" class="hidden lg:inline-block px-4 font-display font-bold-text-xl hover:underline">
|
||||
How to guides
|
||||
</a>
|
||||
<a href="/reference/" class="hidden lg:inline-block px-4 font-display font-bold-text-xl hover:underline">
|
||||
Language reference
|
||||
</a>
|
||||
<a href="/api/" class="hidden lg:inline-block px-4 font-display font-bold-text-xl hover:underline">
|
||||
Stdlib API
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mx-auto lg:py-16 py-2 lg:grid 2xl:grid-cols-[auto_32rem] lg:grid-cols-[auto_36rem] gap-4 lg:px-10 px-2">
|
||||
<div class="lg:pl-10 table">
|
||||
<div class="table-cell align-middle">
|
||||
<h1 class="font-display font-bold text-c-text-2 lg:text-5xl text-3xl lg:text-left text-center leading-tight">
|
||||
A modern, type safe,
|
||||
<br class="hidden lg:inline-block">
|
||||
secure language
|
||||
<br class="hidden lg:inline-block">
|
||||
compiled to PHP
|
||||
</h1>
|
||||
<p class="font-display text-c-text text-xl pt-6 lg:pr-12">
|
||||
Inspired by Rust, Zig and Swift, THP has a modern syntax, semantics,
|
||||
type system and stdlib.
|
||||
</p>
|
||||
<br>
|
||||
<br>
|
||||
<div class="text-center">
|
||||
<a class="inline-block font-display text-lg rounded-full border-2 border-pink-400 py-2 px-8
|
||||
transition-colors hover:text-black hover:bg-pink-400" href="/learn/">
|
||||
Tutorial
|
||||
</a>
|
||||
|
||||
<a class="inline-block font-display text-lg border-2 border-sky-400 py-2 px-8 mx-6 rounded-full
|
||||
transition-colors hover:text-black hover:bg-sky-400" href="/install/">
|
||||
Install
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-[var(--code-theme-bg-color)] lg:p-6 p-2 rounded-lg relative">
|
||||
<span class="absolute lg:inline-block hidden h-[35rem] w-[35rem] -z-10 top-1/2 left-1/2 rounded-full
|
||||
transform -translate-x-1/2 -translate-y-1/2" style="background-image: conic-gradient(from 180deg at 50% 50%,#5BCEFA 0deg,#a853ba 180deg,#F5A9B8 1turn);
|
||||
filter: blur(75px); opacity: 0.75;">
|
||||
</span>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14">
|
||||
<g fill="none" fill-rule="evenodd" transform="translate(1 1)">
|
||||
<circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle>
|
||||
<circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle>
|
||||
<circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle>
|
||||
</g>
|
||||
</svg>
|
||||
<div class="h-1"></div>
|
||||
<div id="editor" class="font-mono language-thp"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/highlighter.js"></script>
|
||||
<script>
|
||||
let jar = CodeJar(document.getElementById("editor"), thp_highlighter, {
|
||||
tab: " ",
|
||||
});
|
||||
|
||||
jar.updateCode(
|
||||
`// Actual generics & sum types
|
||||
fun find_person(Int person_id) -> Result[String, String] {
|
||||
// Easy, explicit error bubbling
|
||||
try Person::find_by_id(person_id)
|
||||
}
|
||||
|
||||
val id = POST::get("person_id") ?? exit("Null person_id")
|
||||
// Errors as values
|
||||
val person = try find_person(person_id: id) with error {
|
||||
eprint("Error: {error}")
|
||||
exit("Person not found")
|
||||
}
|
||||
|
||||
// First class HTML-like templates & components
|
||||
print(
|
||||
<a href="/person/reports/{person.id}">
|
||||
welcome, {person.name}
|
||||
</a>
|
||||
)
|
||||
// And more!`
|
||||
)
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,97 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>THP: Typed Hypertext Processor</title>
|
||||
|
||||
<!-- Tailwind output -->
|
||||
<link href="/css/out.css" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="/css/xcode-colors.css">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500;600;700;800;900&family=Fira+Code&display=swap"
|
||||
rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body class="bg-c-bg text-c-text">
|
||||
<nav class="fixed w-screen top-0 h-12 border-b border-[rgba(150,150,150,0.25)] bg-c-nav-bg backdrop-blur-md z-20">
|
||||
<div class="container mx-auto h-full w-full flex items-center">
|
||||
<a href="/" class="font-display font-bold text-2xl">
|
||||
<span class="text-[#F5A9B8]">t</span><span>h</span><span class="text-[#5BCEFA]">p</span>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="lg:grid lg:grid-cols-[14rem_auto_12rem] container mx-auto">
|
||||
<div class="pt-12 lg:h-screen lg:sticky top-0">
|
||||
<nav id="sidebar" class="py-4 pr-2 overflow-x-scroll lg:h-[calc(100vh-3rem)]"
|
||||
>
|
||||
{{pages}}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<main class="lg:py-[3.5rem] lg:pl-12 lg:pr-4 markdown min-w-0">
|
||||
{{markdown}}
|
||||
</main>
|
||||
|
||||
<div class="lg:pt-12 pt-4 max-h-screen overflow-x-scroll sticky top-0">
|
||||
<nav class="rounded-md lg:mt-10">
|
||||
<h2 class="font-display font-medium pb-2 text-c-text-2">On this page</h2>
|
||||
|
||||
{{sidebar}}
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
let current_uri = window.location.pathname;
|
||||
if (!current_uri.endsWith("/") && !current_uri.endsWith(".html")) {
|
||||
current_uri += ".html";
|
||||
}
|
||||
|
||||
const sidebar = document.getElementById("sidebar");
|
||||
const links = sidebar.querySelectorAll("a");
|
||||
for (const link of [...links]) {
|
||||
if (link.getAttribute("href") === current_uri) {
|
||||
console.log(sidebar.offsetTop);
|
||||
console.log(link.offsetTop);
|
||||
|
||||
const viewport_middle = window.innerHeight / 2;
|
||||
|
||||
sidebar.scrollTop = link.offsetTop - sidebar.offsetTop - 250;
|
||||
|
||||
link.classList.add("bg-pink-200", "dark:bg-pink-950");
|
||||
// link.scrollIntoView({ behavior: "instant", block: "nearest", inline: "nearest" });
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script src="/js/highlighter.js"></script>
|
||||
<script>
|
||||
// Add an editor to all code samples
|
||||
|
||||
const code_elements = document.querySelectorAll(".language-thp");
|
||||
|
||||
for (const el of [...code_elements]) {
|
||||
const pre_parent = el.parentElement;
|
||||
const new_div = document.createElement("div");
|
||||
const code = el.innerText;
|
||||
|
||||
el.parentElement.classList.add("language-thp");
|
||||
pre_parent.removeChild(el);
|
||||
pre_parent.appendChild(new_div);
|
||||
|
||||
CodeJar(new_div, thp_highlighter, {
|
||||
tab: " "
|
||||
}).updateCode(code);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,8 +1,8 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./static/**/*.html"],
|
||||
theme: {
|
||||
extend: {
|
||||
export default {
|
||||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"c-bg": "var(--c-bg)",
|
||||
"c-text": "var(--c-text)",
|
||||
@ -22,8 +22,8 @@ module.exports = {
|
||||
"display": ["Inter", "'Josefin Sans'", "'Fugaz One'", "sans-serif"],
|
||||
"body": ["Inter", "sans-serif"],
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
},
|
||||
corePlugins: {
|
||||
container: false
|
||||
},
|
||||
plugins: [
|
||||
@ -48,4 +48,3 @@ module.exports = {
|
||||
}
|
||||
],
|
||||
}
|
||||
|
@ -1,27 +1,3 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
// Some stricter flags
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noPropertyAccessFromIndexSignature": true
|
||||
}
|
||||
}
|
||||
"extends": "astro/tsconfigs/strictest"
|
||||
}
|
Loading…
Reference in New Issue
Block a user