From 6eeedaf1566de833e7b26745708ab99c4ce2cef6 Mon Sep 17 00:00:00 2001 From: Hunter Johnston Date: Sat, 20 Jan 2024 23:38:45 -0500 Subject: [PATCH] add code blocks section --- .../.cache/v0.3.4/data-IIEYXV7W.json | 58 +++--- .contentlayer/generated/Doc/_index.json | 46 ++--- .contentlayer/generated/Doc/_index.mjs | 4 +- .../generated/Doc/guide__code-blocks.md.json | 4 +- content/guide/code-blocks.md | 190 ++++++++++++++++++ mdsvex.config.js | 48 ++++- src/lib/components/markdown/h2.svelte | 2 +- src/lib/components/markdown/pre.svelte | 10 +- src/lib/styles/app.pcss | 2 +- src/lib/styles/markdown.pcss | 54 ++--- 10 files changed, 326 insertions(+), 92 deletions(-) diff --git a/.contentlayer/.cache/v0.3.4/data-IIEYXV7W.json b/.contentlayer/.cache/v0.3.4/data-IIEYXV7W.json index 7bd3506..a790582 100644 --- a/.contentlayer/.cache/v0.3.4/data-IIEYXV7W.json +++ b/.contentlayer/.cache/v0.3.4/data-IIEYXV7W.json @@ -1,13 +1,39 @@ { "cacheItemsMap": { + "index.md": { + "document": { + "title": "Documentation", + "description": "This is the index page of the '/docs' route.", + "body": { + "raw": "\nOftentimes, we'll simply redirect the user to the first relevant page in the documentation if they land on the `/docs` route.\n\nHowever, if you wanted to make this page the introduction page, you could certainly do so.\n", + "html": "

Oftentimes, we'll simply redirect the user to the first relevant page in the documentation if they land on the /docs route.

\n

However, if you wanted to make this page the introduction page, you could certainly do so.

" + }, + "_id": "index.md", + "_raw": { + "sourceFilePath": "index.md", + "sourceFileName": "index.md", + "sourceFileDir": ".", + "contentType": "markdown", + "flattenedPath": "" + }, + "type": "Doc", + "slug": "", + "slugFull": "/", + "fileName": "index", + "suffix": ".md" + }, + "documentHash": "1705806523564", + "hasWarnings": false, + "documentTypeName": "Doc" + }, "guide/code-blocks.md": { "document": { "title": "Code Blocks", "description": "Learn how to use and customize code blocks.", "tagline": "Guide", "body": { - "raw": "", - "html": "" + "raw": "\nHaving a good code block experience is important for any documentation site. This template uses [shikiji](https://shikiji.netlify.app/guide/) and [rehype-pretty-code](https://rehype-pretty-code.netlify.app/) to style and highlight code blocks.\n\n## Basic usage\n\nTo use a code block, simply wrap your code in a fenced code block and specify the language:\n\n````md\n```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n## Meta Strings\n\nCode blocks are customized using meta strings. Meta strings are strings that are added to the end of the language name in the fenced code block. For example, the following code block has a meta string of `title=\"example.ts\"`:\n\n````md\n```ts title=\"example.ts\"\nconsole.log(\"hello\");\n```\n````\n\nYou can use multiple meta strings in a single code block, and they can be in any order, separated by spaces.\n\nThe following sections will cover some of the meta strings that this template has been setup to use, but you can find a full list of meta strings in the [rehype-pretty-code documentation](https://rehype-pretty-code.netlify.app/#meta-strings).\n\n### Titles\n\nYou can add a title to your code block by adding a title to the fenced code block:\n\n````md\n```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n### Line numbers\n\nTo display line numbers, add the `showLineNumbers` option to the fenced code block:\n\n````md\n```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n### Highlight lines\n\nTo highlight specific lines, include brackets containing a comma-separated list of line numbers:\n\n````md\n```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n\n### Highlight ranges\n\nYou can also specify a range of lines to highlight within the brackets:\n\n````md\n```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n\n### Group highlighted lines\n\nYou can group highlighted lines by ID by adding a `#` followed by an ID immediately following the brackets:\n\n````md\n```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n\nCurrently, we only have out of the box styling for the `remove` and `add` IDs, but you can add your own custom ones by updating the styling in the `markdown.postcss` file.\n\n## Language support\n\nThe following languages are supported and highlighted out of the box:\n\n- Plaintext\n- Shellscript\n- TypeScript\n- CSS\n- Svelte\n- Markdown\n\nWe don't include JavaScript, as TypeScript can adequately handle it.\n\nIf you'd like to add support for additional languages, you can do so by adding the language to the `prettyCodeOptions` object in the `mdsvex.config.js` file:\n\n```ts title=\"mdsvex.config.js\"\nconst prettyCodeOptions = {\n\t// ...\n\tgetHighlighter: (options) =>\n\t\tgetHighlighter({\n\t\t\t...options,\n\t\t\tlangs: [\n\t\t\t\t\"plaintext\",\n\t\t\t\timport(\"shikiji/langs/typescript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/css.mjs\"),\n\t\t\t\timport(\"shikiji/langs/svelte.mjs\"),\n\t\t\t\timport(\"shikiji/langs/shellscript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/markdown.mjs\")\n\t\t\t]\n\t\t})\n\t// ...\n};\n```\n\nIt's important to only include the languages you need, as importing all of the languages will increase the bundle size of your site, thus increasing the load time.\n", + "html": "

Having a good code block experience is important for any documentation site. This template uses shikiji and rehype-pretty-code to style and highlight code blocks.

\n

Basic usage

\n

To use a code block, simply wrap your code in a fenced code block and specify the language:

\n
```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Meta Strings

\n

Code blocks are customized using meta strings. Meta strings are strings that are added to the end of the language name in the fenced code block. For example, the following code block has a meta string of title=\"example.ts\":

\n
```ts title=\"example.ts\"\nconsole.log(\"hello\");\n```\n
\n

You can use multiple meta strings in a single code block, and they can be in any order, separated by spaces.

\n

The following sections will cover some of the meta strings that this template has been setup to use, but you can find a full list of meta strings in the rehype-pretty-code documentation.

\n

Titles

\n

You can add a title to your code block by adding a title to the fenced code block:

\n
```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Line numbers

\n

To display line numbers, add the showLineNumbers option to the fenced code block:

\n
```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Highlight lines

\n

To highlight specific lines, include brackets containing a comma-separated list of line numbers:

\n
```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n
\n

Highlight ranges

\n

You can also specify a range of lines to highlight within the brackets:

\n
```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n
\n

Group highlighted lines

\n

You can group highlighted lines by ID by adding a # followed by an ID immediately following the brackets:

\n
```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n
\n

The markdown above will render the following:

\n
console.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n
\n

Currently, we only have out of the box styling for the remove and add IDs, but you can add your own custom ones by updating the styling in the markdown.postcss file.

\n

Language support

\n

The following languages are supported and highlighted out of the box:

\n\n

We don't include JavaScript, as TypeScript can adequately handle it.

\n

If you'd like to add support for additional languages, you can do so by adding the language to the prettyCodeOptions object in the mdsvex.config.js file:

\n
const prettyCodeOptions = {\n\t// ...\n\tgetHighlighter: (options) =>\n\t\tgetHighlighter({\n\t\t\t...options,\n\t\t\tlangs: [\n\t\t\t\t\"plaintext\",\n\t\t\t\timport(\"shikiji/langs/typescript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/css.mjs\"),\n\t\t\t\timport(\"shikiji/langs/svelte.mjs\"),\n\t\t\t\timport(\"shikiji/langs/shellscript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/markdown.mjs\")\n\t\t\t]\n\t\t})\n\t// ...\n};\n
\n

It's important to only include the languages you need, as importing all of the languages will increase the bundle size of your site, thus increasing the load time.

" }, "_id": "guide/code-blocks.md", "_raw": { @@ -23,7 +49,7 @@ "fileName": "code-blocks", "suffix": ".md" }, - "documentHash": "1705806527407", + "documentHash": "1705811643667", "hasWarnings": false, "documentTypeName": "Doc" }, @@ -81,32 +107,6 @@ "hasWarnings": false, "documentTypeName": "Doc" }, - "index.md": { - "document": { - "title": "Documentation", - "description": "This is the index page of the '/docs' route.", - "body": { - "raw": "\nOftentimes, we'll simply redirect the user to the first relevant page in the documentation if they land on the `/docs` route.\n\nHowever, if you wanted to make this page the introduction page, you could certainly do so.\n", - "html": "

Oftentimes, we'll simply redirect the user to the first relevant page in the documentation if they land on the /docs route.

\n

However, if you wanted to make this page the introduction page, you could certainly do so.

" - }, - "_id": "index.md", - "_raw": { - "sourceFilePath": "index.md", - "sourceFileName": "index.md", - "sourceFileDir": ".", - "contentType": "markdown", - "flattenedPath": "" - }, - "type": "Doc", - "slug": "", - "slugFull": "/", - "fileName": "index", - "suffix": ".md" - }, - "documentHash": "1705806523564", - "hasWarnings": false, - "documentTypeName": "Doc" - }, "guide/index.md": { "document": { "title": "Introduction", diff --git a/.contentlayer/generated/Doc/_index.json b/.contentlayer/generated/Doc/_index.json index de7bebd..25e5f70 100644 --- a/.contentlayer/generated/Doc/_index.json +++ b/.contentlayer/generated/Doc/_index.json @@ -1,11 +1,32 @@ [ + { + "title": "Documentation", + "description": "This is the index page of the '/docs' route.", + "body": { + "raw": "\nOftentimes, we'll simply redirect the user to the first relevant page in the documentation if they land on the `/docs` route.\n\nHowever, if you wanted to make this page the introduction page, you could certainly do so.\n", + "html": "

Oftentimes, we'll simply redirect the user to the first relevant page in the documentation if they land on the /docs route.

\n

However, if you wanted to make this page the introduction page, you could certainly do so.

" + }, + "_id": "index.md", + "_raw": { + "sourceFilePath": "index.md", + "sourceFileName": "index.md", + "sourceFileDir": ".", + "contentType": "markdown", + "flattenedPath": "" + }, + "type": "Doc", + "slug": "", + "slugFull": "/", + "fileName": "index", + "suffix": ".md" + }, { "title": "Code Blocks", "description": "Learn how to use and customize code blocks.", "tagline": "Guide", "body": { - "raw": "", - "html": "" + "raw": "\nHaving a good code block experience is important for any documentation site. This template uses [shikiji](https://shikiji.netlify.app/guide/) and [rehype-pretty-code](https://rehype-pretty-code.netlify.app/) to style and highlight code blocks.\n\n## Basic usage\n\nTo use a code block, simply wrap your code in a fenced code block and specify the language:\n\n````md\n```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n## Meta Strings\n\nCode blocks are customized using meta strings. Meta strings are strings that are added to the end of the language name in the fenced code block. For example, the following code block has a meta string of `title=\"example.ts\"`:\n\n````md\n```ts title=\"example.ts\"\nconsole.log(\"hello\");\n```\n````\n\nYou can use multiple meta strings in a single code block, and they can be in any order, separated by spaces.\n\nThe following sections will cover some of the meta strings that this template has been setup to use, but you can find a full list of meta strings in the [rehype-pretty-code documentation](https://rehype-pretty-code.netlify.app/#meta-strings).\n\n### Titles\n\nYou can add a title to your code block by adding a title to the fenced code block:\n\n````md\n```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n### Line numbers\n\nTo display line numbers, add the `showLineNumbers` option to the fenced code block:\n\n````md\n```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n### Highlight lines\n\nTo highlight specific lines, include brackets containing a comma-separated list of line numbers:\n\n````md\n```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n\n### Highlight ranges\n\nYou can also specify a range of lines to highlight within the brackets:\n\n````md\n```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n\n### Group highlighted lines\n\nYou can group highlighted lines by ID by adding a `#` followed by an ID immediately following the brackets:\n\n````md\n```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n\nCurrently, we only have out of the box styling for the `remove` and `add` IDs, but you can add your own custom ones by updating the styling in the `markdown.postcss` file.\n\n## Language support\n\nThe following languages are supported and highlighted out of the box:\n\n- Plaintext\n- Shellscript\n- TypeScript\n- CSS\n- Svelte\n- Markdown\n\nWe don't include JavaScript, as TypeScript can adequately handle it.\n\nIf you'd like to add support for additional languages, you can do so by adding the language to the `prettyCodeOptions` object in the `mdsvex.config.js` file:\n\n```ts title=\"mdsvex.config.js\"\nconst prettyCodeOptions = {\n\t// ...\n\tgetHighlighter: (options) =>\n\t\tgetHighlighter({\n\t\t\t...options,\n\t\t\tlangs: [\n\t\t\t\t\"plaintext\",\n\t\t\t\timport(\"shikiji/langs/typescript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/css.mjs\"),\n\t\t\t\timport(\"shikiji/langs/svelte.mjs\"),\n\t\t\t\timport(\"shikiji/langs/shellscript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/markdown.mjs\")\n\t\t\t]\n\t\t})\n\t// ...\n};\n```\n\nIt's important to only include the languages you need, as importing all of the languages will increase the bundle size of your site, thus increasing the load time.\n", + "html": "

Having a good code block experience is important for any documentation site. This template uses shikiji and rehype-pretty-code to style and highlight code blocks.

\n

Basic usage

\n

To use a code block, simply wrap your code in a fenced code block and specify the language:

\n
```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Meta Strings

\n

Code blocks are customized using meta strings. Meta strings are strings that are added to the end of the language name in the fenced code block. For example, the following code block has a meta string of title=\"example.ts\":

\n
```ts title=\"example.ts\"\nconsole.log(\"hello\");\n```\n
\n

You can use multiple meta strings in a single code block, and they can be in any order, separated by spaces.

\n

The following sections will cover some of the meta strings that this template has been setup to use, but you can find a full list of meta strings in the rehype-pretty-code documentation.

\n

Titles

\n

You can add a title to your code block by adding a title to the fenced code block:

\n
```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Line numbers

\n

To display line numbers, add the showLineNumbers option to the fenced code block:

\n
```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Highlight lines

\n

To highlight specific lines, include brackets containing a comma-separated list of line numbers:

\n
```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n
\n

Highlight ranges

\n

You can also specify a range of lines to highlight within the brackets:

\n
```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n
\n

Group highlighted lines

\n

You can group highlighted lines by ID by adding a # followed by an ID immediately following the brackets:

\n
```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n
\n

The markdown above will render the following:

\n
console.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n
\n

Currently, we only have out of the box styling for the remove and add IDs, but you can add your own custom ones by updating the styling in the markdown.postcss file.

\n

Language support

\n

The following languages are supported and highlighted out of the box:

\n\n

We don't include JavaScript, as TypeScript can adequately handle it.

\n

If you'd like to add support for additional languages, you can do so by adding the language to the prettyCodeOptions object in the mdsvex.config.js file:

\n
const prettyCodeOptions = {\n\t// ...\n\tgetHighlighter: (options) =>\n\t\tgetHighlighter({\n\t\t\t...options,\n\t\t\tlangs: [\n\t\t\t\t\"plaintext\",\n\t\t\t\timport(\"shikiji/langs/typescript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/css.mjs\"),\n\t\t\t\timport(\"shikiji/langs/svelte.mjs\"),\n\t\t\t\timport(\"shikiji/langs/shellscript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/markdown.mjs\")\n\t\t\t]\n\t\t})\n\t// ...\n};\n
\n

It's important to only include the languages you need, as importing all of the languages will increase the bundle size of your site, thus increasing the load time.

" }, "_id": "guide/code-blocks.md", "_raw": { @@ -65,27 +86,6 @@ "fileName": "configuration", "suffix": ".md" }, - { - "title": "Documentation", - "description": "This is the index page of the '/docs' route.", - "body": { - "raw": "\nOftentimes, we'll simply redirect the user to the first relevant page in the documentation if they land on the `/docs` route.\n\nHowever, if you wanted to make this page the introduction page, you could certainly do so.\n", - "html": "

Oftentimes, we'll simply redirect the user to the first relevant page in the documentation if they land on the /docs route.

\n

However, if you wanted to make this page the introduction page, you could certainly do so.

" - }, - "_id": "index.md", - "_raw": { - "sourceFilePath": "index.md", - "sourceFileName": "index.md", - "sourceFileDir": ".", - "contentType": "markdown", - "flattenedPath": "" - }, - "type": "Doc", - "slug": "", - "slugFull": "/", - "fileName": "index", - "suffix": ".md" - }, { "title": "Introduction", "description": "What is this?", diff --git a/.contentlayer/generated/Doc/_index.mjs b/.contentlayer/generated/Doc/_index.mjs index 057ab74..4402665 100644 --- a/.contentlayer/generated/Doc/_index.mjs +++ b/.contentlayer/generated/Doc/_index.mjs @@ -1,9 +1,9 @@ // NOTE This file is auto-generated by Contentlayer +import indexMd from './index.md.json' assert { type: 'json' } import guide__codeBlocksMd from './guide__code-blocks.md.json' assert { type: 'json' } import guide__componentsMd from './guide__components.md.json' assert { type: 'json' } import guide__configurationMd from './guide__configuration.md.json' assert { type: 'json' } -import indexMd from './index.md.json' assert { type: 'json' } import guide__indexMd from './guide__index.md.json' assert { type: 'json' } -export const allDocs = [guide__codeBlocksMd, guide__componentsMd, guide__configurationMd, indexMd, guide__indexMd] +export const allDocs = [indexMd, guide__codeBlocksMd, guide__componentsMd, guide__configurationMd, guide__indexMd] diff --git a/.contentlayer/generated/Doc/guide__code-blocks.md.json b/.contentlayer/generated/Doc/guide__code-blocks.md.json index d46111f..ebb2d14 100644 --- a/.contentlayer/generated/Doc/guide__code-blocks.md.json +++ b/.contentlayer/generated/Doc/guide__code-blocks.md.json @@ -3,8 +3,8 @@ "description": "Learn how to use and customize code blocks.", "tagline": "Guide", "body": { - "raw": "", - "html": "" + "raw": "\nHaving a good code block experience is important for any documentation site. This template uses [shikiji](https://shikiji.netlify.app/guide/) and [rehype-pretty-code](https://rehype-pretty-code.netlify.app/) to style and highlight code blocks.\n\n## Basic usage\n\nTo use a code block, simply wrap your code in a fenced code block and specify the language:\n\n````md\n```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n## Meta Strings\n\nCode blocks are customized using meta strings. Meta strings are strings that are added to the end of the language name in the fenced code block. For example, the following code block has a meta string of `title=\"example.ts\"`:\n\n````md\n```ts title=\"example.ts\"\nconsole.log(\"hello\");\n```\n````\n\nYou can use multiple meta strings in a single code block, and they can be in any order, separated by spaces.\n\nThe following sections will cover some of the meta strings that this template has been setup to use, but you can find a full list of meta strings in the [rehype-pretty-code documentation](https://rehype-pretty-code.netlify.app/#meta-strings).\n\n### Titles\n\nYou can add a title to your code block by adding a title to the fenced code block:\n\n````md\n```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n### Line numbers\n\nTo display line numbers, add the `showLineNumbers` option to the fenced code block:\n\n````md\n```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n````\n\nThe markdown above will render the following:\n\n```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n\n### Highlight lines\n\nTo highlight specific lines, include brackets containing a comma-separated list of line numbers:\n\n````md\n```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n\n### Highlight ranges\n\nYou can also specify a range of lines to highlight within the brackets:\n\n````md\n```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n\n### Group highlighted lines\n\nYou can group highlighted lines by ID by adding a `#` followed by an ID immediately following the brackets:\n\n````md\n```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n````\n\nThe markdown above will render the following:\n\n```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n\nCurrently, we only have out of the box styling for the `remove` and `add` IDs, but you can add your own custom ones by updating the styling in the `markdown.postcss` file.\n\n## Language support\n\nThe following languages are supported and highlighted out of the box:\n\n- Plaintext\n- Shellscript\n- TypeScript\n- CSS\n- Svelte\n- Markdown\n\nWe don't include JavaScript, as TypeScript can adequately handle it.\n\nIf you'd like to add support for additional languages, you can do so by adding the language to the `prettyCodeOptions` object in the `mdsvex.config.js` file:\n\n```ts title=\"mdsvex.config.js\"\nconst prettyCodeOptions = {\n\t// ...\n\tgetHighlighter: (options) =>\n\t\tgetHighlighter({\n\t\t\t...options,\n\t\t\tlangs: [\n\t\t\t\t\"plaintext\",\n\t\t\t\timport(\"shikiji/langs/typescript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/css.mjs\"),\n\t\t\t\timport(\"shikiji/langs/svelte.mjs\"),\n\t\t\t\timport(\"shikiji/langs/shellscript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/markdown.mjs\")\n\t\t\t]\n\t\t})\n\t// ...\n};\n```\n\nIt's important to only include the languages you need, as importing all of the languages will increase the bundle size of your site, thus increasing the load time.\n", + "html": "

Having a good code block experience is important for any documentation site. This template uses shikiji and rehype-pretty-code to style and highlight code blocks.

\n

Basic usage

\n

To use a code block, simply wrap your code in a fenced code block and specify the language:

\n
```ts\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Meta Strings

\n

Code blocks are customized using meta strings. Meta strings are strings that are added to the end of the language name in the fenced code block. For example, the following code block has a meta string of title=\"example.ts\":

\n
```ts title=\"example.ts\"\nconsole.log(\"hello\");\n```\n
\n

You can use multiple meta strings in a single code block, and they can be in any order, separated by spaces.

\n

The following sections will cover some of the meta strings that this template has been setup to use, but you can find a full list of meta strings in the rehype-pretty-code documentation.

\n

Titles

\n

You can add a title to your code block by adding a title to the fenced code block:

\n
```ts title=\"example.ts\"\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Line numbers

\n

To display line numbers, add the showLineNumbers option to the fenced code block:

\n
```ts showLineNumbers\nconst name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\nconsole.log(`Hello, ${name}!`);\n
\n

Highlight lines

\n

To highlight specific lines, include brackets containing a comma-separated list of line numbers:

\n
```ts {1,3}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n
\n

Highlight ranges

\n

You can also specify a range of lines to highlight within the brackets:

\n
```ts {1,3-5,7}\nconst name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n```\n
\n

The markdown above will render the following:

\n
const name: string = \"world\";\n\nfunction sayHello(name: string): void {\n\tconsole.log(`Hello, ${name}!`);\n}\n\nsayHello(name);\n
\n

Group highlighted lines

\n

You can group highlighted lines by ID by adding a # followed by an ID immediately following the brackets:

\n
```ts {1,4}#remove {3,5-6}#add\nconsole.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n```\n
\n

The markdown above will render the following:

\n
console.log(\"Hello, world!\");\n\nfunction getNameByUserId(userId: string): string {\n\tconsole.log(`Getting name for user ${userId}...`);\n\treturn \"some name\";\n}\n
\n

Currently, we only have out of the box styling for the remove and add IDs, but you can add your own custom ones by updating the styling in the markdown.postcss file.

\n

Language support

\n

The following languages are supported and highlighted out of the box:

\n\n

We don't include JavaScript, as TypeScript can adequately handle it.

\n

If you'd like to add support for additional languages, you can do so by adding the language to the prettyCodeOptions object in the mdsvex.config.js file:

\n
const prettyCodeOptions = {\n\t// ...\n\tgetHighlighter: (options) =>\n\t\tgetHighlighter({\n\t\t\t...options,\n\t\t\tlangs: [\n\t\t\t\t\"plaintext\",\n\t\t\t\timport(\"shikiji/langs/typescript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/css.mjs\"),\n\t\t\t\timport(\"shikiji/langs/svelte.mjs\"),\n\t\t\t\timport(\"shikiji/langs/shellscript.mjs\"),\n\t\t\t\timport(\"shikiji/langs/markdown.mjs\")\n\t\t\t]\n\t\t})\n\t// ...\n};\n
\n

It's important to only include the languages you need, as importing all of the languages will increase the bundle size of your site, thus increasing the load time.

" }, "_id": "guide/code-blocks.md", "_raw": { diff --git a/content/guide/code-blocks.md b/content/guide/code-blocks.md index be09e58..5517a65 100644 --- a/content/guide/code-blocks.md +++ b/content/guide/code-blocks.md @@ -3,3 +3,193 @@ title: Code Blocks description: Learn how to use and customize code blocks. tagline: Guide --- + +Having a good code block experience is important for any documentation site. This template uses [shikiji](https://shikiji.netlify.app/guide/) and [rehype-pretty-code](https://rehype-pretty-code.netlify.app/) to style and highlight code blocks. + +## Basic usage + +To use a code block, simply wrap your code in a fenced code block and specify the language: + +````md +```ts +const name: string = "world"; +console.log(`Hello, ${name}!`); +``` +```` + +The markdown above will render the following: + +```ts +const name: string = "world"; +console.log(`Hello, ${name}!`); +``` + +## Meta Strings + +Code blocks are customized using meta strings. Meta strings are strings that are added to the end of the language name in the fenced code block. For example, the following code block has a meta string of `title="example.ts"`: + +````md +```ts title="example.ts" +console.log("hello"); +``` +```` + +You can use multiple meta strings in a single code block, and they can be in any order, separated by spaces. + +The following sections will cover some of the meta strings that this template has been setup to use, but you can find a full list of meta strings in the [rehype-pretty-code documentation](https://rehype-pretty-code.netlify.app/#meta-strings). + +### Titles + +You can add a title to your code block by adding a title to the fenced code block: + +````md +```ts title="example.ts" +const name: string = "world"; +console.log(`Hello, ${name}!`); +``` +```` + +The markdown above will render the following: + +```ts title="example.ts" +const name: string = "world"; +console.log(`Hello, ${name}!`); +``` + +### Line numbers + +To display line numbers, add the `showLineNumbers` option to the fenced code block: + +````md +```ts showLineNumbers +const name: string = "world"; +console.log(`Hello, ${name}!`); +``` +```` + +The markdown above will render the following: + +```ts showLineNumbers +const name: string = "world"; +console.log(`Hello, ${name}!`); +``` + +### Highlight lines + +To highlight specific lines, include brackets containing a comma-separated list of line numbers: + +````md +```ts {1,3} +const name: string = "world"; + +function sayHello(name: string): void { + console.log(`Hello, ${name}!`); +} + +sayHello(name); +``` +```` + +The markdown above will render the following: + +```ts {1,3} +const name: string = "world"; + +function sayHello(name: string): void { + console.log(`Hello, ${name}!`); +} + +sayHello(name); +``` + +### Highlight ranges + +You can also specify a range of lines to highlight within the brackets: + +````md +```ts {1,3-5,7} +const name: string = "world"; + +function sayHello(name: string): void { + console.log(`Hello, ${name}!`); +} + +sayHello(name); +``` +```` + +The markdown above will render the following: + +```ts {1,3-5,7} +const name: string = "world"; + +function sayHello(name: string): void { + console.log(`Hello, ${name}!`); +} + +sayHello(name); +``` + +### Group highlighted lines + +You can group highlighted lines by ID by adding a `#` followed by an ID immediately following the brackets: + +````md +```ts {1,4}#remove {3,5-6}#add +console.log("Hello, world!"); + +function getNameByUserId(userId: string): string { + console.log(`Getting name for user ${userId}...`); + return "some name"; +} +``` +```` + +The markdown above will render the following: + +```ts {1,4}#remove {3,5-6}#add +console.log("Hello, world!"); + +function getNameByUserId(userId: string): string { + console.log(`Getting name for user ${userId}...`); + return "some name"; +} +``` + +Currently, we only have out of the box styling for the `remove` and `add` IDs, but you can add your own custom ones by updating the styling in the `markdown.postcss` file. + +## Language support + +The following languages are supported and highlighted out of the box: + +- Plaintext +- Shellscript +- TypeScript +- CSS +- Svelte +- Markdown + +We don't include JavaScript, as TypeScript can adequately handle it. + +If you'd like to add support for additional languages, you can do so by adding the language to the `prettyCodeOptions` object in the `mdsvex.config.js` file: + +```ts title="mdsvex.config.js" +const prettyCodeOptions = { + // ... + getHighlighter: (options) => + getHighlighter({ + ...options, + langs: [ + "plaintext", + import("shikiji/langs/typescript.mjs"), + import("shikiji/langs/css.mjs"), + import("shikiji/langs/svelte.mjs"), + import("shikiji/langs/shellscript.mjs"), + import("shikiji/langs/markdown.mjs") + ] + }) + // ... +}; +``` + +It's important to only include the languages you need, as importing all of the languages will increase the bundle size of your site, thus increasing the load time. diff --git a/mdsvex.config.js b/mdsvex.config.js index df8f1a5..e0ce223 100644 --- a/mdsvex.config.js +++ b/mdsvex.config.js @@ -60,17 +60,31 @@ export const mdsvexOptions = { backticks: false, dashes: false }, - remarkPlugins: [remarkGfm, remarkRemovePrettierIgnore, remarkEscapeCode], + remarkPlugins: [ + // use remark-gfm to support GitHub Flavored Markdown + remarkGfm, + // remove prettier-ignore comments from code blocks + remarkRemovePrettierIgnore, + // escape code blocks so they can be used within Svelte components + remarkEscapeCode + ], rehypePlugins: [ + // convert to
 so it can be processed by rehype-pretty-code
 		rehypeComponentPreToPre,
+		// syntax highlight code blocks with rehype-pretty-code
 		[rehypePrettyCode, prettyCodeOptions],
+		// apply data-metadata to 
elements that contain a
rehypeHandleMetadata, + // render code blocks as HTML so they can be used within Svelte components rehypeRenderCode, + // convert
 back to  before rendering
 		rehypePreToComponentPre,
+		// add IDs to headings for table of contents links
 		rehypeSlug
 	]
 };
 
+// The entities we want to escape in code blocks, along with their replacements.
 const entities = [
 	[//g, ">"],
@@ -79,10 +93,17 @@ const entities = [
 ];
 
 /**
- * Removes `` and `// prettier-ignore` from code blocks.
+ * Removes `` and `// prettier-ignore` from code blocks
+ * before they are converted to HTML for syntax highlighting.
+ *
  * We do this because sometimes we want to force a line break in code blocks, but
  * prettier removes them, however, we don't want to include the ignore statement
  * in the final code block.
+ *
+ * One caveat is that if you did want to include the ignore statement in the final
+ * code block, you'd have to do some hacky stuff like including it in the comment
+ * itself and checking for it in the code block, but that's not something we need
+ * at the moment.
  */
 function remarkRemovePrettierIgnore() {
 	return async (tree) => {
@@ -94,6 +115,9 @@ function remarkRemovePrettierIgnore() {
 	};
 }
 
+/**
+ * Escapes code blocks so that they can be used within Svelte components.
+ */
 function remarkEscapeCode() {
 	return async (tree) => {
 		visit(tree, "inlineCode", escape);
@@ -106,6 +130,11 @@ function remarkEscapeCode() {
 	};
 }
 
+/**
+ * Converts the `` component created by mdsvex to a regular `
`
+ * element so it can be processed by `rehype-pretty-code` or any other rehype plugin
+ * that expects a `
` element.
+ */
 function rehypeComponentPreToPre() {
 	return async (tree) => {
 		visit(tree, (node) => {
@@ -116,6 +145,9 @@ function rehypeComponentPreToPre() {
 	};
 }
 
+/**
+ * Converts `
` elements back to `` before they are rendered.
+ */
 function rehypePreToComponentPre() {
 	return async (tree) => {
 		visit(tree, (node) => {
@@ -126,6 +158,11 @@ function rehypePreToComponentPre() {
 	};
 }
 
+/**
+ * Adds `data-metadata` to `
` elements that contain a `
`. + * We use this to style elements within the `
` differently if a `
` + * is present. + */ function rehypeHandleMetadata() { return async (tree) => { visit(tree, (node) => { @@ -148,6 +185,9 @@ function rehypeHandleMetadata() { }; } +/** + * Renders `
` elements as HTML so they can be used within Svelte components.
+ */
 function rehypeRenderCode() {
 	return async (tree) => {
 		visit(tree, (node) => {
@@ -176,6 +216,10 @@ function rehypeRenderCode() {
 	};
 }
 
+/**
+ * Converts tabs to spaces to make wider code blocks fit better
+ * on smaller screens.
+ */
 function tabsToSpaces(code) {
 	return code.replaceAll("    ", "  ").replaceAll("\t", "  ");
 }
diff --git a/src/lib/components/markdown/h2.svelte b/src/lib/components/markdown/h2.svelte
index 0b2a245..96e92b6 100644
--- a/src/lib/components/markdown/h2.svelte
+++ b/src/lib/components/markdown/h2.svelte
@@ -6,7 +6,7 @@
 
 
 

diff --git a/src/lib/components/markdown/pre.svelte b/src/lib/components/markdown/pre.svelte index fb4af54..a30b19b 100644 --- a/src/lib/components/markdown/pre.svelte +++ b/src/lib/components/markdown/pre.svelte @@ -1,19 +1,11 @@ -
+
 		
 
diff --git a/src/lib/styles/app.pcss b/src/lib/styles/app.pcss index 37cac21..c998481 100644 --- a/src/lib/styles/app.pcss +++ b/src/lib/styles/app.pcss @@ -9,7 +9,7 @@ --foreground: 320 7% 8%; --muted: 320 4.8% 93%; - --muted-foreground: 320 3.8% 38.1%; + --muted-foreground: 320 3.8% 34.1%; --popover: 0 0% 98%; --popover-foreground: 320 7% 8%; diff --git a/src/lib/styles/markdown.pcss b/src/lib/styles/markdown.pcss index 94040a4..711a8bc 100644 --- a/src/lib/styles/markdown.pcss +++ b/src/lib/styles/markdown.pcss @@ -29,7 +29,7 @@ @apply relative; & pre { - @apply mb-4 mt-6 overflow-x-auto rounded-lg border border-border py-4 text-sm font-medium; + @apply mb-4 mt-6 overflow-x-auto rounded-lg border border-border bg-[#f1f1f1] py-4 text-sm font-medium; } & code { @@ -39,7 +39,7 @@ } & [data-line] { - @apply inline-block min-h-[1.5rem] w-full border-l-2 border-l-transparent py-0.5; + @apply inline-block min-h-[1.5rem] w-full border-l-2 border-l-transparent px-4 py-0.5; } & [data-chars-id] { @@ -47,32 +47,20 @@ } & [data-highlighted-line] { - @apply w-full border-l-primary bg-muted; + @apply z-10 w-full border-l-primary bg-foreground/5; } - & [data-line-numbers] [data-line] { - @apply px-2; + & [data-highlighted-line][data-highlighted-line-id="add"] { + @apply border-l-green-600 data-[highlighted-line-id="add"]:bg-green-100; } -} -[data-chars-id="ul"] { - @apply border-b border-border font-bold !important; -} - -[data-chars-id="hi"] { - @apply rounded bg-accent/[0.1] p-1 font-bold !important; -} - -[data-chars-id="r"] { - @apply border-border font-bold !important; -} - -[data-chars-id="t"] { - @apply border-b font-bold !important; -} + & [data-highlighted-line][data-highlighted-line-id="remove"] { + @apply border-l-red-600 data-[highlighted-line-id="remove"]:bg-red-100; + } -[data-chars-id="c"] { - @apply border-b font-bold !important; + & [data-line-numbers] [data-line] { + @apply -ml-2 pr-2; + } } [data-rehype-pretty-code-title] { @@ -93,10 +81,30 @@ code[data-theme*=" "] span { background-color: var(--shiki-light-bg); } +/* Dark mode specific overrides */ + .dark { & code[data-theme*=" "], code[data-theme*=" "] span { color: var(--shiki-dark); background-color: var(--shiki-dark-bg); } + + & [data-rehype-pretty-code-figure] { + & pre { + @apply bg-[#181818]; + } + + & [data-highlighted-line] { + @apply bg-muted; + } + + & [data-highlighted-line][data-highlighted-line-id="add"] { + @apply border-l-green-500 data-[highlighted-line-id="add"]:bg-green-600/20; + } + + & [data-highlighted-line][data-highlighted-line-id="remove"] { + @apply border-l-red-500 data-[highlighted-line-id="remove"]:bg-red-500/20; + } + } }