diff --git a/public/Iosevka/Bold.woff2 b/public/Iosevka/Bold.woff2 new file mode 100644 index 0000000..63b588f Binary files /dev/null and b/public/Iosevka/Bold.woff2 differ diff --git a/public/Iosevka/Heavy.woff2 b/public/Iosevka/Heavy.woff2 new file mode 100644 index 0000000..b639cd5 Binary files /dev/null and b/public/Iosevka/Heavy.woff2 differ diff --git a/public/Iosevka/Regular.woff2 b/public/Iosevka/Regular.woff2 new file mode 100644 index 0000000..1446bf3 Binary files /dev/null and b/public/Iosevka/Regular.woff2 differ diff --git a/public/css/global.css b/public/css/global.css index a415589..42134c5 100644 --- a/public/css/global.css +++ b/public/css/global.css @@ -1,3 +1,22 @@ +/* Iosevka web */ +@font-face { + font-family: "Iosevka Fixed Web"; + font-display: swap; + font-weight: 400; + font-stretch: normal; + font-style: normal; + src: url("/Iosevka/Regular.woff2") format("woff2"); +} + +@font-face { + font-family: 'Iosevka Fixed Web'; + font-display: swap; + font-weight: 700; + font-stretch: normal; + font-style: normal; + src: url('/Iosevka/Bold.woff2') format('woff2'); +} + :root { --c-bg: #121212; @@ -49,7 +68,7 @@ body { } pre, code { - font-family: Iosevka, 'Fira Code', monospace; + font-family: "Iosevka Fixed Web", "Iosevka Nerd Font", Iosevka, monospace; } .button-effect-receiver { diff --git a/src/components/InteractiveCode.astro b/src/components/InteractiveCode.astro new file mode 100644 index 0000000..58fe499 --- /dev/null +++ b/src/components/InteractiveCode.astro @@ -0,0 +1,81 @@ +--- +const {code} = Astro.props; + +let c = trimAndDedent(code as string); + +/** + * Performs the following: + * - Removes the first & last line, if they are empty + * - Picks the indentation level from the first non-white line + * - Dedents the following lines +*/ +function trimAndDedent(input: string): string { + let lines = input.split("\n"); + + // Remove empty lines at the start + while (lines[0] === "") { + lines = lines.slice(1); + } + + // Get indentation level + let indentationLevel = 0; + for (const char of lines[0]!) { + if (char === " ") { + indentationLevel += 1; + } else { + break; + } + } + + // Enforce indentation, or trim + for (let i = 0; i < lines.length; i += 1) { + // If the line is empty, continue + const characters = lines[i]!.split(""); + if (characters.length === 0) { + continue; + } + + // If all characters are whitespace, append just a newline + const nonWhitespace = characters.find((x) => x !== " "); + if (nonWhitespace === undefined) { + lines[i] = ""; + continue; + } + + // Enforce indentation + if (characters.length < indentationLevel) { + throw new Error("Invalid indentation while parsing THP code: " + lines[i]); + } + let currentIndentation = 0; + for (const c of characters) { + if (c === " ") { currentIndentation += 1 } + else {break;} + } + if (currentIndentation < indentationLevel) { + throw new Error("Invalid indentation while parsing THP code: " + lines[i]); + } + + lines[i] = characters.slice(4).join(""); + } + + + // Remove empty lines at the end + let endPosition = lines.length - 1; + while (true) { + if (lines[endPosition] === "") { + lines = lines.slice(0, -1); + endPosition -= 1; + } else { + break; + } + } + + return lines.join("\n"); +} + +--- + +
+ Interactive code :D +
{c}
+
diff --git a/src/layouts/PagesLayout.astro b/src/layouts/PagesLayout.astro index e6db589..2efb4f1 100644 --- a/src/layouts/PagesLayout.astro +++ b/src/layouts/PagesLayout.astro @@ -6,7 +6,7 @@ import Sidebar from "../components/Sidebar.astro"; const { frontmatter, headings } = Astro.props; -const posts = await Astro.glob("../pages/learn/**/*.md"); +const posts = await Astro.glob("../pages/learn/**/*.{md,mdx}"); // The index.md page must have a `pagesLayout` frontmatter, which declares the order of all the pages. const indexSubpath = `/learn/index.md`; @@ -35,7 +35,7 @@ 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"), + post.file.endsWith(entry.path + ".md") || post.file.endsWith(entry.path + ".mdx"), ); if (pageData === undefined) { @@ -116,6 +116,10 @@ for (const entry of pagesIndex) { for (const e of [...code_elements]) { const el = e as HTMLElement; + // Some elements with .language-thp don't want to be processed + if (e.getAttribute("data-disabled") !== null) { + continue; + } const pre_parent = el.parentElement!; const new_div = document.createElement("div"); const code = el.innerText; diff --git a/src/pages/learn/basics/hello-world.md b/src/pages/learn/basics/hello-world.md deleted file mode 100644 index 74c8efa..0000000 --- a/src/pages/learn/basics/hello-world.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -layout: ../../../layouts/PagesLayout.astro -title: Hello world ---- - -# Hello, world! - -Create a file named `hello.thp` with the contents: - -```thp -print("Hello, world!") -``` - -Then run `thp hello.thp` diff --git a/src/pages/learn/basics/hello-world.mdx b/src/pages/learn/basics/hello-world.mdx new file mode 100644 index 0000000..9acf22b --- /dev/null +++ b/src/pages/learn/basics/hello-world.mdx @@ -0,0 +1,31 @@ +--- +layout: ../../../layouts/PagesLayout.astro +title: Hello world +--- +import InteractiveCode from "../../../components/InteractiveCode.astro"; + +# Hello, world! + +Create a file named `hello.thp` with the contents: + +```thp +print("Hello, world!") +``` + +Then run `thp hello.thp` + +## Try + + diff --git a/tailwind.config.mjs b/tailwind.config.mjs index 49ab9cd..085460e 100644 --- a/tailwind.config.mjs +++ b/tailwind.config.mjs @@ -19,7 +19,7 @@ export default { } }, fontFamily: { - "mono": ["Iosevka", "'Iosevka Nerd Font'", "'Fira Code'", "monospace"], + "mono": ["'Iosevka Fixed Web'", "Iosevka", "'Iosevka Nerd Font'", "monospace"], "display": ["Inter", "'Josefin Sans'", "'Fugaz One'", "sans-serif"], "body": ["Inter", "sans-serif"], },