diff --git a/bun.lockb b/bun.lockb index 268d346..c837de6 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 8c7a44e..078b90f 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/src/components/TableOfContents.astro b/src/components/TableOfContents.astro index 1f1cf04..7572ab7 100644 --- a/src/components/TableOfContents.astro +++ b/src/components/TableOfContents.astro @@ -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

- // if (heading.depth === 2) { - // toc.push(heading); - // } else { - // parentHeadings.get(heading.depth - 1).subheadings.push(heading); - // } - toc.push(heading); - }); - return toc; -} --- \ No newline at end of file +

On this page

+ + + \ No newline at end of file diff --git a/src/components/TableOfContentsHeading.astro b/src/components/TableOfContentsHeading.astro index f2cc35e..765c226 100644 --- a/src/components/TableOfContentsHeading.astro +++ b/src/components/TableOfContentsHeading.astro @@ -8,12 +8,39 @@ const { heading } = Astro.props; {heading.text} { - heading.subheadings.length > 0 && ( + heading.children.length > 0 && ( ) } - \ No newline at end of file + + \ No newline at end of file diff --git a/src/content/resources/daemon-settings.mdx b/src/content/resources/daemon-settings.mdx index b7b79e1..ce383fd 100644 --- a/src/content/resources/daemon-settings.mdx +++ b/src/content/resources/daemon-settings.mdx @@ -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' @@ -30,14 +30,14 @@ Configuration options are organized by their respective areas: Files, Wallet, Ne | download_dir | string | local downloads folder | 'c:\lbry\lbrynet\' | Location of downloaded output files | ### 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 | -| max_key_fee | json | \{'currency': 'USD', 'amount': 50.0} | \{'currency': 'LBC', 'amount': 5.0} | Max payment allowed for content | -| wallet | string | 'lbryum' | 'lbrycrd' | Choice of wallet software, SPV (lbryum) vs full node (lbrycrd). Currently only lbryum supported | -| use_keyring | boolean | false | true | Store wallet password in keyring (not currently available) | +| 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 | +| max_key_fee | json | \{'currency': 'USD', 'amount': 50.0} | \{'currency': 'LBC', 'amount': 5.0} | Max payment allowed for content | +| wallet | string | 'lbryum' | 'lbrycrd' | Choice of wallet software, SPV (lbryum) vs full node (lbrycrd). Currently only lbryum supported | +| use_keyring | boolean | false | true | Store wallet password in keyring (not currently available) | diff --git a/src/layouts/Collections.astro b/src/layouts/Collections.astro new file mode 100644 index 0000000..c9347ab --- /dev/null +++ b/src/layouts/Collections.astro @@ -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('/'); +} + +--- + + +
+ +
+
+ +
+

{frontmatter.title}

+

{description}

+ +
+
+
+
+ +
\ No newline at end of file diff --git a/src/layouts/Markdown.astro b/src/layouts/Markdown.astro index 38b84d8..a4ee05d 100644 --- a/src/layouts/Markdown.astro +++ b/src/layouts/Markdown.astro @@ -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); ---
-
- {items.length ? ( - {collection.charAt(0).toUpperCase() + collection.slice(1)} - - ) : null} -
-
-

{frontmatter.title}

-

{description}

- +
+
+ {headings && ( + + )} +
+

{frontmatter.title}

+

{description}

+ +
+
-
- -
\ No newline at end of file diff --git a/src/pages/resources.astro b/src/pages/resources.astro index 67c29fa..fd2e472 100644 --- a/src/pages/resources.astro +++ b/src/pages/resources.astro @@ -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 = { } --- - + - \ No newline at end of file + \ No newline at end of file diff --git a/src/pages/resources/[slug].astro b/src/pages/resources/[slug].astro index fd65cd6..6335f1c 100644 --- a/src/pages/resources/[slug].astro +++ b/src/pages/resources/[slug].astro @@ -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'); diff --git a/src/pages/spec.astro b/src/pages/spec.astro index c8a2ce8..ebb9caa 100644 --- a/src/pages/spec.astro +++ b/src/pages/spec.astro @@ -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(/(?#{1,6})\s+(?.+)/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 - {md} +}} headings={headings}> + {} \ No newline at end of file diff --git a/src/pages/tutorials.astro b/src/pages/tutorials.astro index cda4444..f48328b 100644 --- a/src/pages/tutorials.astro +++ b/src/pages/tutorials.astro @@ -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." diff --git a/src/pages/tutorials/[slug].astro b/src/pages/tutorials/[slug].astro index c5f810b..8cfde61 100644 --- a/src/pages/tutorials/[slug].astro +++ b/src/pages/tutorials/[slug].astro @@ -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'); diff --git a/src/styles/Header.css b/src/styles/Header.css index 19b45ea..b57875a 100644 --- a/src/styles/Header.css +++ b/src/styles/Header.css @@ -6,7 +6,7 @@ header { header nav { display: flex; justify-content: space-between; - height: 75px; + height: var(--nav-height); padding: 0 20px; } diff --git a/src/styles/global.scss b/src/styles/global.scss index 1dc47c6..f0145f9 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -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 { diff --git a/src/styles/markdown.css b/src/styles/markdown.css index 84e7257..39e7e36 100644 --- a/src/styles/markdown.css +++ b/src/styles/markdown.css @@ -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; @@ -53,104 +56,7 @@ h1 > a, h2 > a, h3 > a, h4 > a, h5 > a, h6 > a { --color-attention-subtle: rgba(187,128,9,0.15); --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; diff --git a/src/utils/generateToc.ts b/src/utils/generateToc.ts new file mode 100644 index 0000000..68cdbe9 --- /dev/null +++ b/src/utils/generateToc.ts @@ -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 = []; + + 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; +} \ No newline at end of file