Markdown Extensions
Relevant source files
The following files were used as context for generating this wiki page:
The Charlotte project enhances the standard Markdown authoring experience by integrating a suite of custom plugins and configurations. These extensions, built upon the Astro content collection framework and the unified (remark/rehype) ecosystem, provide features ranging from automated metadata generation to rich, interactive components embedded directly within Markdown files. This system allows authors to create more expressive and functional content beyond the capabilities of standard Markdown.
The core of this system relies on dependencies declared in package.json, such as remark-directive, astro-expressive-code, and remark-math, which are processed during the site's build process to transform custom syntax into rich HTML.
Sources: package.json:30-58
Frontmatter and Metadata
All posts utilize YAML frontmatter to define essential metadata. This metadata is defined by a schema and is used to control how posts are displayed, categorized, and rendered.
Sources: src/content/posts/2018-10-30/Charlotte-Markdown.md:2-11, src/content/config.ts:3-23
Frontmatter Fields
The following table details the available frontmatter fields for posts, as defined by the content collection schema.
| Attribute | Type | Description | Default |
|---|---|---|---|
title | string | The title of the post. | (required) |
published | date | The publication date of the post. | (required) |
updated | date | The date the post was last updated. | undefined |
draft | boolean | If true, the post will not be displayed on the main site in production. | false |
description | string | A short summary of the post, displayed on list pages. | "" |
image | string | Path to the post's cover image. | "" |
tags | string[] | A list of tags associated with the post. | [] |
category | string | The category of the post. | "" |
lang | string | The language of the post. | "" |
isPinned | boolean | Internal flag to indicate if a post is pinned. | false |
Sources: src/content/config.ts:4-14, frontmatter.json:19-74
Automatic Excerpt Generation
The project uses a custom remark plugin, remark-excerpt, to automatically generate an excerpt for each post. This plugin extracts the text content of the first paragraph in a Markdown document and injects it into the frontmatter as data.astro.frontmatter.excerpt. This allows for consistent post summaries without requiring authors to manually write a description if the first paragraph suffices.
The diagram below illustrates the process of the remark-excerpt plugin.
This diagram shows how the remarkExcerpt function processes a Markdown abstract syntax tree (AST) to find the first paragraph and use its content as the post's excerpt.
Sources: src/plugins/remark-excerpt.js:4-16
Custom Directives
Charlotte leverages remark-directive to support custom container blocks and inline elements. This allows for the creation of components like admonitions and repository cards using a simple, declarative syntax.
Sources: package.json:52, src/content/posts/2018-10-30/Charlotte-Markdown.md:144-189
Admonitions (Alerts)
Admonitions are used to highlight important information. The system supports five types: note, tip, important, warning, and caution. The syntax can also include a custom title.
Syntax Examples:
:::note
This is a note.
:::
:::warning[Custom Title]
This is a warning with a custom title.
:::
The project also supports standard GitHub-flavored admonition syntax (e.g., > [!NOTE]), which is converted to the directive syntax by the remark-github-admonitions-to-directives plugin.
Sources: src/content/posts/2018-10-30/Charlotte-Markdown.md:144-189, package.json:54
GitHub Repository Cards
A dynamic card displaying information about a GitHub repository can be embedded using a ::github directive. The card fetches repository data from the GitHub API on page load.
Syntax:
::github{repo="ChuwuYo/Charlotte"}
This is used on pages like projects.md to showcase a list of repositories.
Sources: src/content/posts/2018-10-30/Charlotte-Markdown.md:133-142, src/content/spec/projects.md:3-9
Spoilers
Inline text can be hidden behind a spoiler tag. The content inside the spoiler is revealed on click and can contain other Markdown formatting.
Syntax:
Content :spoiler[is hidden **here**]!
Sources: src/content/posts/2018-10-30/Charlotte-Markdown.md:191-197
Enhanced Code Blocks
Code blocks are enhanced using astro-expressive-code and a custom toolbar plugin. This provides a rich user experience for viewing and interacting with code.
Sources: package.json:34, src/plugins/expressive-code/code-toolbar.ts
Custom Code Toolbar
A custom plugin, pluginCodeToolbar, adds a toolbar to the top of every code block. The toolbar includes:
- Language Badge: Displays the code block's language.
- Title: An optional title, extracted from the code block's meta string (e.g.,
```js title="My Code"). - Copy Button: Allows users to copy the code to their clipboard.
The following diagram shows the structure of a rendered code block with the custom toolbar.
This diagram illustrates the DOM structure where the custom toolbar is prepended to the pre element within the main .frame container.
The toolbar's appearance, including colors and layout, is defined in src/plugins/expressive-code/code-toolbar.ts and src/styles/markdown.css.
Sources: src/plugins/expressive-code/code-toolbar.ts:133-288, src/styles/markdown.css:66-93
Mathematical Notations
The project supports mathematical formulas written in LaTeX syntax, rendered using KaTeX. This is enabled by the remark-math and rehype-katex plugins.
- Inline formulas are wrapped in single dollar signs:
$\omega = d\phi / dt$. - Block-level formulas are wrapped in double dollar signs:
$$I = \int \rho R^{2} dV$$.
Styling for these rendered formulas, such as handling overflow for wide equations, is provided in src/styles/markdown.css.
Sources: src/content/posts/2018-10-30/Charlotte-Markdown.md:118-131, package.json:55,49, src/styles/markdown.css:127-132