mirror of
https://github.com/LBRYFoundation/lbry-tech.git
synced 2025-03-04 06:57:53 +00:00
make sidebar and toc
This commit is contained in:
parent
7847d58841
commit
c2c1d4807a
16 changed files with 360 additions and 181 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
@ -8,6 +8,7 @@
|
|||
"@thewebforge/astro-code-blocks": "^0.2.0",
|
||||
"astro": "^4.0.3",
|
||||
"astro-preload": "^1.1.2",
|
||||
"markdown-wasm": "^1.2.0",
|
||||
"rehype-autolink-headings": "^7.1.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"sass": "^1.69.5"
|
||||
|
|
|
@ -1,30 +1,25 @@
|
|||
---
|
||||
// TableOfContents.astro
|
||||
import TableOfContentsHeading from "./TableOfContentsHeading.astro";
|
||||
import TocItem from '../utils/generateToc.ts';
|
||||
const { headings } = Astro.props;
|
||||
|
||||
const toc = headings && headings.length ? buildToc(headings) : [];
|
||||
const toc = headings && headings.length ? TocItem(headings) : [];
|
||||
|
||||
console.log(toc);
|
||||
|
||||
function buildToc(headings) {
|
||||
const toc = [];
|
||||
const parentHeadings = new Map();
|
||||
headings.forEach((h) => {
|
||||
const heading = { ...h, subheadings: [] };
|
||||
parentHeadings.set(heading.depth, heading);
|
||||
// Change 2 to 1 if your markdown includes your <h1>
|
||||
// if (heading.depth === 2) {
|
||||
// toc.push(heading);
|
||||
// } else {
|
||||
// parentHeadings.get(heading.depth - 1).subheadings.push(heading);
|
||||
// }
|
||||
toc.push(heading);
|
||||
});
|
||||
return toc;
|
||||
}
|
||||
---
|
||||
|
||||
<nav class="toc">
|
||||
<h2 id="on-this-page">On this page</h2>
|
||||
<ul>
|
||||
{toc.map((heading) => <TableOfContentsHeading heading={heading}/>)}
|
||||
</ul>
|
||||
</nav>
|
||||
<style>
|
||||
.toc ul {
|
||||
list-style: none;
|
||||
padding-inline-start: 0;
|
||||
border-left: 1px solid var(--secondary-background);
|
||||
}
|
||||
</style>
|
|
@ -8,12 +8,39 @@ const { heading } = Astro.props;
|
|||
{heading.text}
|
||||
</a>
|
||||
{
|
||||
heading.subheadings.length > 0 && (
|
||||
heading.children.length > 0 && (
|
||||
<ul>
|
||||
{heading.subheadings.map((subheading) => (
|
||||
<Astro.self heading={subheading} />
|
||||
{heading.children.map((child) => (
|
||||
<Astro.self heading={child} />
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
</li>
|
||||
<style>
|
||||
li a {
|
||||
display: inline-block;
|
||||
font-size: 0.875rem;
|
||||
width: 100%;
|
||||
/* margin-left: 0.3rem; */
|
||||
padding: 0.5em 0.5rem;
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
|
||||
li a.active {
|
||||
color: var(--header-text);
|
||||
background-color: var(--tertiary-background);
|
||||
}
|
||||
|
||||
li a:hover {
|
||||
color: var(--header-text);
|
||||
/* border-left: 1px solid var(--secondary-background); */
|
||||
background-color: var(--tertiary-background);
|
||||
}
|
||||
|
||||
li ul {
|
||||
list-style: none;
|
||||
padding-inline-start: 1rem;
|
||||
/* border-left: 1px solid var(--secondary-background); */
|
||||
}
|
||||
</style>
|
|
@ -10,7 +10,7 @@ This document outlines how to configure SDK daemon settings and what options are
|
|||
The easiest way to configure the settings is by editing the `daemon_settings.yml` file (may need to be created) that resides in the default [lbrynet directory](https://lbry.com/faq/lbry-directories). These settings can also be configured via the [settings_set](https://lbry.tech/api/sdk#settings_set) API call. The [settings_get](https://lbry.tech/api/sdk#settings_get) API call can be used to retrieve current values. Some values will require an SDK restart after being set via the API call.
|
||||
|
||||
Sample daemon_settings.yml file:
|
||||
```
|
||||
```yaml
|
||||
tcp_port: 3335
|
||||
lbryum_servers: ['spv11.lbry.com:50001','spv19.lbry.com:50001']
|
||||
download_directory: 'c:\lbry\Downloads'
|
||||
|
@ -31,7 +31,7 @@ Configuration options are organized by their respective areas: Files, Wallet, Ne
|
|||
|
||||
### Wallet
|
||||
| Setting | Format | Default value | Sample Values | Description |
|
||||
|-----------------|--------|-------------------------------------------------------|----------------------------|------------------------------------------------------------|
|
||||
|-----------------|---------|-------------------------------------------------------|-------------------------------------|---------------------------------------------------------------------------------------------------|
|
||||
| blockchain_name | string | 'lbrycrd_main' | 'lbrycrd_regtest' | Blockchain network to connect to |
|
||||
| lbryum_servers | list | [‘spv11.lbry.com:50001’,‘spv19.lbry.com:50001’] | ["mylbryum.lbry.com:50001] | SPV wallet server address(Default servers are spv11-spv19) |
|
||||
| wallet_dir | string | [varies by OS](https://lbry.com/faq/lbry-directories) | 'c:\lbry\lbryum\' | Wallet data location |
|
||||
|
|
157
src/layouts/Collections.astro
Normal file
157
src/layouts/Collections.astro
Normal file
|
@ -0,0 +1,157 @@
|
|||
---
|
||||
import Layout from './Layout.astro';
|
||||
import { markdown } from '@astropub/md';
|
||||
import { getCollection } from "astro:content";
|
||||
import TableOfContents from '../components/TableOfContents.astro';
|
||||
|
||||
import '../styles/markdown.css';
|
||||
|
||||
const { frontmatter, headings, collection } = Astro.props;
|
||||
const { pathname } = Astro.url;
|
||||
|
||||
const items = await getCollection(collection) || [];
|
||||
|
||||
const description = await markdown(frontmatter.description);
|
||||
|
||||
const isActive = (href: string)=>{
|
||||
return href === pathname || href === pathname.split('/').slice(0,2).join('/');
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
<Layout title={frontmatter.title}>
|
||||
<div class="wrapper">
|
||||
<section class="sidebar">
|
||||
<div class="container">
|
||||
{items.length ? (
|
||||
<summary>
|
||||
<a class="title" href={`/${collection}`}>{collection.charAt(0).toUpperCase() + collection.slice(1)}</a>
|
||||
</summary>
|
||||
<ul>
|
||||
{items.map(item=> (
|
||||
<li class:list={[isActive(`/${item.collection}/${item.slug}`) ? "active": ""]}><a href={`/${item.collection}/${item.slug}`}>{item.data.title}</a></li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
</div>
|
||||
</section>
|
||||
<div class="main">
|
||||
<div class="content">
|
||||
<aside class="toc">
|
||||
<TableOfContents headings={headings} />
|
||||
</aside>
|
||||
<div class="markdown-body">
|
||||
<h1>{frontmatter.title}</h1>
|
||||
<h3>{description}</h3>
|
||||
<slot/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.wrapper {
|
||||
display: flex;
|
||||
--sidebar-width: 300px;
|
||||
/* max-width: 1000px; */
|
||||
}
|
||||
|
||||
.wrapper .sidebar {
|
||||
position: fixed;
|
||||
width: var(--sidebar-width);
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
inset-block: 0;
|
||||
inset-inline-start: 0;
|
||||
/* padding: 20px; */
|
||||
padding-top: var(--nav-height);
|
||||
background-color: var(--secondary-background);
|
||||
}
|
||||
|
||||
.wrapper .sidebar .container {
|
||||
padding: 1rem 1rem 0;
|
||||
}
|
||||
|
||||
.wrapper .sidebar summary .title {
|
||||
/* font-size: 1.5rem; */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.wrapper .sidebar ul {
|
||||
list-style: none;
|
||||
margin: 0.5rem;
|
||||
padding-inline-start: 0;
|
||||
/* border-left: 1px solid var(--background); */
|
||||
}
|
||||
|
||||
.wrapper .sidebar ul li {
|
||||
/* width: fit-content; */
|
||||
/* height: fit-content; */
|
||||
/* padding: 10px 20px; */
|
||||
border-left: 1px solid var(--background);
|
||||
}
|
||||
|
||||
.wrapper .sidebar ul li a {
|
||||
display: inline-block;
|
||||
font-size: 0.875rem;
|
||||
width: 100%;
|
||||
margin-left: 0.3rem;
|
||||
padding: 0.5em 0.5rem;
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
|
||||
.wrapper .sidebar ul li.active {
|
||||
border-left: 1px solid var(--header-text);
|
||||
}
|
||||
|
||||
.wrapper .sidebar ul li.active a {
|
||||
background-color: var(--tertiary-background);
|
||||
|
||||
}
|
||||
|
||||
.wrapper .sidebar ul li.active a, .wrapper .sidebar ul li a:hover {
|
||||
color: var(--header-text);
|
||||
}
|
||||
|
||||
.wrapper .main {
|
||||
width: 100vw;
|
||||
padding-inline-start: var(--sidebar-width);
|
||||
}
|
||||
|
||||
.wrapper .main .content {
|
||||
display: flex;
|
||||
/* width: fit-content; */
|
||||
/* max-width: 100%; */
|
||||
order: 1;
|
||||
margin: 20px 0 0 20px;
|
||||
}
|
||||
|
||||
.wrapper .main aside {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
order: 2;
|
||||
width: fit-content;
|
||||
max-width: 25%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.wrapper .markdown-body {
|
||||
/* margin: 10px 20px; */
|
||||
max-width: 75%;
|
||||
}
|
||||
|
||||
.wrapper .toc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 750px) {
|
||||
.wrapper .sidebar {
|
||||
transform: translateX(-80%);
|
||||
}
|
||||
|
||||
.wrapper .main {
|
||||
padding-inline-start: calc(var(--sidebar-width) * 0.2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</Layout>
|
|
@ -8,48 +8,74 @@ import '../styles/markdown.css';
|
|||
|
||||
const { frontmatter, headings, collection } = Astro.props;
|
||||
|
||||
const items = await getCollection(collection) || [];
|
||||
const items = collection ? await getCollection(collection) : [];
|
||||
|
||||
const description = await markdown(frontmatter.description)
|
||||
const description = await markdown(frontmatter.description);
|
||||
|
||||
---
|
||||
|
||||
<Layout title={frontmatter.title}>
|
||||
<div class="wrapper">
|
||||
<section>
|
||||
{items.length ? (
|
||||
<a href={`/${collection}`}>{collection.charAt(0).toUpperCase() + collection.slice(1)}</a>
|
||||
<ul>
|
||||
{items.map(item=> (
|
||||
<li><a href={`/${item.collection}/${item.slug}`}>{item.data.title}</a></li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
</section>
|
||||
<div class="main">
|
||||
<div class="content">
|
||||
{headings && (
|
||||
<aside class="toc">
|
||||
<TableOfContents headings={headings} />
|
||||
</aside>
|
||||
)}
|
||||
<div class="markdown-body">
|
||||
<h1>{frontmatter.title}</h1>
|
||||
<h3>{description}</h3>
|
||||
<slot/>
|
||||
</div>
|
||||
<section class="toc">
|
||||
<TableOfContents headings={headings} />
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.wrapper {
|
||||
display: flex;
|
||||
margin: 20px;
|
||||
/* max-width: 1000px; */
|
||||
}
|
||||
|
||||
.wrapper .main {
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.wrapper .main .content {
|
||||
display: flex;
|
||||
/* width: fit-content; */
|
||||
/* max-width: 100%; */
|
||||
order: 1;
|
||||
margin: 20px 0 0 20px;
|
||||
}
|
||||
|
||||
.wrapper .main aside {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
order: 2;
|
||||
width: fit-content;
|
||||
max-width: 25%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.wrapper .markdown-body {
|
||||
margin: 10px 20px;
|
||||
max-width: 1000px;
|
||||
/* margin: 10px 20px; */
|
||||
max-width: 75%;
|
||||
}
|
||||
|
||||
.wrapper .toc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 750px) {
|
||||
.wrapper .sidebar {
|
||||
transform: translateX(-80%);
|
||||
}
|
||||
|
||||
.wrapper .main {
|
||||
padding-inline-start: calc(400px * 0.2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</Layout>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import Markdown from '../layouts/Markdown.astro';
|
||||
import Collections from '../layouts/Collections.astro';
|
||||
|
||||
const frontmatter = {
|
||||
title: "Find the LBRY specification, API documentation, our Contributor’s guide, and more in the Resources area.",
|
||||
|
@ -7,6 +7,6 @@ const frontmatter = {
|
|||
}
|
||||
---
|
||||
|
||||
<Markdown title="Resources" frontmatter={frontmatter} collection="resources">
|
||||
<Collections title="Resources" frontmatter={frontmatter} collection="resources">
|
||||
|
||||
</Markdown>
|
||||
</Collections>
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import Markdown from '../../layouts/Markdown.astro';
|
||||
import Markdown from '../../layouts/Collections.astro';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const entries = await getCollection('resources');
|
||||
|
|
|
@ -3,19 +3,32 @@ import Markdown from '../layouts/Markdown.astro';
|
|||
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
|
||||
import rehypeSlug from 'rehype-slug';
|
||||
|
||||
import markdown from 'markdown-wasm';
|
||||
|
||||
// import { markdown } from '@astropub/md'
|
||||
|
||||
|
||||
import { markdown } from '@astropub/md'
|
||||
|
||||
|
||||
const content = await (await fetch('https://raw.githubusercontent.com/lbryio/spec/master/index.md')).text();
|
||||
const md = await markdown(content.replace(`---
|
||||
let content = await (await fetch('https://raw.githubusercontent.com/lbryio/spec/master/index.md')).text();
|
||||
// const md = await markdown(content.replace(`---
|
||||
// layout: spec
|
||||
// ---`, ''), {
|
||||
// rehypePlugins: [
|
||||
// [rehypeSlug as any],
|
||||
// [rehypeAutolinkHeadings as any, { behavior: 'wrap' }]
|
||||
// ]
|
||||
// });
|
||||
content = content.replace(`---
|
||||
layout: spec
|
||||
---`, ''), {
|
||||
rehypePlugins: [
|
||||
[rehypeSlug as any],
|
||||
[rehypeAutolinkHeadings as any, { behavior: 'wrap' }]
|
||||
]
|
||||
---`, '')
|
||||
|
||||
// Extract the headings from the markdown
|
||||
const headings = content.match(/(?<flag>#{1,6})\s+(?<content>.+)/g).map(heading=>{
|
||||
const text = heading.replaceAll('#', '').replace(' ', '');
|
||||
return {
|
||||
depth: heading.replace(/[^#]/g, "").length, // Get number of '#' a heading has
|
||||
slug: text.replaceAll(' ', '-').toLowerCase(), // URL friendly path
|
||||
text
|
||||
}
|
||||
});
|
||||
|
||||
---
|
||||
|
@ -23,6 +36,6 @@ layout: spec
|
|||
<Markdown frontmatter={{
|
||||
title: "Spec",
|
||||
description: "*Alex Grintsvayg (grin@lbry.com), Jeremy Kauffman (jeremy@lbry.com)*"
|
||||
}}>
|
||||
{md}
|
||||
}} headings={headings}>
|
||||
{<Fragment set:html={markdown.parse(content)}/>}
|
||||
</Markdown>
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import Markdown from '../layouts/Markdown.astro';
|
||||
import Markdown from '../layouts/Collections.astro';
|
||||
|
||||
const frontmatter = {
|
||||
description: "Find the LBRY specification, API documentation, our Contributor's guide, and more in the Resources area."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import Markdown from '../../layouts/Markdown.astro';
|
||||
import Markdown from '../../layouts/Collections.astro';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const entries = await getCollection('tutorials');
|
||||
|
|
|
@ -6,7 +6,7 @@ header {
|
|||
header nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 75px;
|
||||
height: var(--nav-height);
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
--tertiary-background: #041523;
|
||||
--header-text: #FAFAFA;
|
||||
--body-text: #DDDDDD;
|
||||
--nav-height: 75px;
|
||||
|
||||
--astro-code-color-text: white;
|
||||
--astro-code-color-background: black;
|
||||
|
@ -30,7 +31,7 @@
|
|||
|
||||
html {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
margin-top: 75px;
|
||||
margin-top: var(--nav-height);
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,7 @@ main {
|
|||
footer {
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
|
|
|
@ -3,10 +3,9 @@ h1 > a, h2 > a, h3 > a, h4 > a, h5 > a, h6 > a {
|
|||
}
|
||||
|
||||
/* Source: https://github.com/sindresorhus/github-markdown-css */
|
||||
/* With some modifications */
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.markdown-body,
|
||||
[data-theme="dark"] {
|
||||
.markdown-body {
|
||||
/*dark*/
|
||||
color-scheme: dark;
|
||||
--color-prettylights-syntax-comment: #8b949e;
|
||||
|
@ -42,10 +41,14 @@ h1 > a, h2 > a, h3 > a, h4 > a, h5 > a, h6 > a {
|
|||
--color-fg-default: #e6edf3;
|
||||
--color-fg-muted: #7d8590;
|
||||
--color-fg-subtle: #6e7681;
|
||||
--color-canvas-default: #0d1117;
|
||||
--color-canvas-subtle: #161b22;
|
||||
--color-border-default: #30363d;
|
||||
--color-border-muted: #21262d;
|
||||
/* --color-canvas-default: #0d1117; */
|
||||
--color-canvas-default: var(--tertiary-background);
|
||||
/* --color-canvas-subtle: #161b22; */
|
||||
--color-canvas-subtle: var(--secondary-background);
|
||||
/* --color-border-default: #30363d; */
|
||||
--color-border-default: var(--secondary-background);
|
||||
/* --color-border-muted: #21262d; */
|
||||
--color-border-muted: var(--tertiary-background);
|
||||
--color-neutral-muted: rgba(110,118,129,0.4);
|
||||
--color-accent-fg: #2f81f7;
|
||||
--color-accent-emphasis: #1f6feb;
|
||||
|
@ -54,103 +57,6 @@ h1 > a, h2 > a, h3 > a, h4 > a, h5 > a, h6 > a {
|
|||
--color-danger-fg: #f85149;
|
||||
--color-done-fg: #a371f7;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.markdown-body,
|
||||
[data-theme="light"] {
|
||||
/*light*/
|
||||
color-scheme: light;
|
||||
--color-prettylights-syntax-comment: #6e7781;
|
||||
--color-prettylights-syntax-constant: #0550ae;
|
||||
--color-prettylights-syntax-entity: #6639ba;
|
||||
--color-prettylights-syntax-storage-modifier-import: #24292f;
|
||||
--color-prettylights-syntax-entity-tag: #116329;
|
||||
--color-prettylights-syntax-keyword: #cf222e;
|
||||
--color-prettylights-syntax-string: #0a3069;
|
||||
--color-prettylights-syntax-variable: #953800;
|
||||
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
|
||||
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
|
||||
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
|
||||
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
|
||||
--color-prettylights-syntax-carriage-return-bg: #cf222e;
|
||||
--color-prettylights-syntax-string-regexp: #116329;
|
||||
--color-prettylights-syntax-markup-list: #3b2300;
|
||||
--color-prettylights-syntax-markup-heading: #0550ae;
|
||||
--color-prettylights-syntax-markup-italic: #24292f;
|
||||
--color-prettylights-syntax-markup-bold: #24292f;
|
||||
--color-prettylights-syntax-markup-deleted-text: #82071e;
|
||||
--color-prettylights-syntax-markup-deleted-bg: #ffebe9;
|
||||
--color-prettylights-syntax-markup-inserted-text: #116329;
|
||||
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
|
||||
--color-prettylights-syntax-markup-changed-text: #953800;
|
||||
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
|
||||
--color-prettylights-syntax-markup-ignored-text: #eaeef2;
|
||||
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
|
||||
--color-prettylights-syntax-meta-diff-range: #8250df;
|
||||
--color-prettylights-syntax-brackethighlighter-angle: #57606a;
|
||||
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;
|
||||
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
|
||||
--color-fg-default: #1F2328;
|
||||
--color-fg-muted: #656d76;
|
||||
--color-fg-subtle: #6e7781;
|
||||
--color-canvas-default: #ffffff;
|
||||
--color-canvas-subtle: #f6f8fa;
|
||||
--color-border-default: #d0d7de;
|
||||
--color-border-muted: hsla(210,18%,87%,1);
|
||||
--color-neutral-muted: rgba(175,184,193,0.2);
|
||||
--color-accent-fg: #0969da;
|
||||
--color-accent-emphasis: #0969da;
|
||||
--color-attention-fg: #9a6700;
|
||||
--color-attention-subtle: #fff8c5;
|
||||
--color-danger-fg: #d1242f;
|
||||
--color-done-fg: #8250df;
|
||||
--color-prettylights-syntax-comment: #6e7781;
|
||||
--color-prettylights-syntax-constant: #0550ae;
|
||||
--color-prettylights-syntax-entity: #6639ba;
|
||||
--color-prettylights-syntax-storage-modifier-import: #24292f;
|
||||
--color-prettylights-syntax-entity-tag: #116329;
|
||||
--color-prettylights-syntax-keyword: #cf222e;
|
||||
--color-prettylights-syntax-string: #0a3069;
|
||||
--color-prettylights-syntax-variable: #953800;
|
||||
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
|
||||
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
|
||||
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
|
||||
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
|
||||
--color-prettylights-syntax-carriage-return-bg: #cf222e;
|
||||
--color-prettylights-syntax-string-regexp: #116329;
|
||||
--color-prettylights-syntax-markup-list: #3b2300;
|
||||
--color-prettylights-syntax-markup-heading: #0550ae;
|
||||
--color-prettylights-syntax-markup-italic: #24292f;
|
||||
--color-prettylights-syntax-markup-bold: #24292f;
|
||||
--color-prettylights-syntax-markup-deleted-text: #82071e;
|
||||
--color-prettylights-syntax-markup-deleted-bg: #ffebe9;
|
||||
--color-prettylights-syntax-markup-inserted-text: #116329;
|
||||
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
|
||||
--color-prettylights-syntax-markup-changed-text: #953800;
|
||||
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
|
||||
--color-prettylights-syntax-markup-ignored-text: #eaeef2;
|
||||
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
|
||||
--color-prettylights-syntax-meta-diff-range: #8250df;
|
||||
--color-prettylights-syntax-brackethighlighter-angle: #57606a;
|
||||
--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;
|
||||
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
|
||||
--color-fg-default: #1F2328;
|
||||
--color-fg-muted: #656d76;
|
||||
--color-fg-subtle: #6e7781;
|
||||
--color-canvas-default: #ffffff;
|
||||
--color-canvas-subtle: #f6f8fa;
|
||||
--color-border-default: #d0d7de;
|
||||
--color-border-muted: hsla(210,18%,87%,1);
|
||||
--color-neutral-muted: rgba(175,184,193,0.2);
|
||||
--color-accent-fg: #0969da;
|
||||
--color-accent-emphasis: #0969da;
|
||||
--color-attention-fg: #9a6700;
|
||||
--color-attention-subtle: #fff8c5;
|
||||
--color-danger-fg: #d1242f;
|
||||
--color-done-fg: #8250df;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
font-size: 16px;
|
||||
|
|
52
src/utils/generateToc.ts
Normal file
52
src/utils/generateToc.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Source: https://github.com/withastro/docs/blob/882e0b0a9d16d1c822cb8c230a62a4bfcd308605/src/util/generateToc.ts
|
||||
|
||||
import type { MarkdownHeading } from 'astro';
|
||||
export interface TocItem extends MarkdownHeading {
|
||||
children: TocItem[];
|
||||
}
|
||||
|
||||
function diveChildren(item: TocItem, depth: number): TocItem[] {
|
||||
if (depth === 1) {
|
||||
return item.children;
|
||||
} else {
|
||||
// e.g., 2
|
||||
return diveChildren(item.children[item.children.length - 1], depth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
export default function generateToc(headings: MarkdownHeading[], title = 'Overview') {
|
||||
// const overview = { depth: 2, slug: 'overview', text: title };
|
||||
headings = [...headings.filter(({ depth }) => depth > 1 && depth < 4)];
|
||||
const toc: Array<TocItem> = [];
|
||||
|
||||
for (const heading of headings) {
|
||||
if (toc.length === 0) {
|
||||
toc.push({
|
||||
...heading,
|
||||
children: [],
|
||||
});
|
||||
} else {
|
||||
const lastItemInToc = toc[toc.length - 1];
|
||||
if (heading.depth < lastItemInToc.depth) {
|
||||
throw new Error(`Orphan heading found: ${heading.text}.`);
|
||||
}
|
||||
if (heading.depth === lastItemInToc.depth) {
|
||||
// same depth
|
||||
toc.push({
|
||||
...heading,
|
||||
children: [],
|
||||
});
|
||||
} else {
|
||||
// higher depth
|
||||
// push into children, or children' children alike
|
||||
const gap = heading.depth - lastItemInToc.depth;
|
||||
const target = diveChildren(lastItemInToc, gap);
|
||||
target.push({
|
||||
...heading,
|
||||
children: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return toc;
|
||||
}
|
Loading…
Reference in a new issue