本サイトで利用可能なMDX記法一覧
このページでは、本サイトで使用しているMDXの記法について説明します。
MDXは、Markdownをベースとしつつ、JSXをMarkdown内に記述することを可能としたマークアップ言語です。一部利用できないMarkdown(CommonMark)の記法がありますが、概ねCommonMarkに準拠しています。
また、本サイトではGitHub Flavored Markdown(GFM)で定義されている機能も利用できます。GFMはCommonMarkのスーパーセットであり、URLの自動リンク化や脚注、打ち消し線や表組みなど、CommonMarkにはない機能を提供しています。
さらに、本サイト独自の拡張機能として、コールアウトやリンクカード、埋め込みなどの機能を提供しています。
以下に利用可能なMDX記法を示します。
見出し
# 見出し1
## 見出し2
### 見出し3
#### 見出し4
##### 見出し5
###### 見出し6
見出し1
見出し2
見出し3
見出し4
見出し5
見出し6
アクセシビリティの観点から、見出しはレベル2から始めてください。
これは、慣例的に見出し1は文書のタイトルとして使用されるためです。本サイトでは、文書のタイトルはフロントマターで指定するため、見出し1を使用することはありません。
見出し1, 2, …はそれぞれHTMLのh1
, h2
, …として最終的に表示されます。したがって、MDX内でもHTMLの慣例に則り、以下のリンクに示されているように見出し1は1つのページに1つだけ使用することが推奨されます。
見出し5, 6は、一般的には使用されません。見出しのレベルが深くなると、文書の構造が複雑になり、読みにくくなるためです。
また、h5
, h6
のスタイルは@tailwindcss/typographyで意図的に実装されていないことからも、見出し5, 6の使用は推奨されません。
リスト
箇条書き
- リスト1
- リスト2
- リスト2-1
- リスト2-2
- リスト1
- リスト2
- リスト2-1
- リスト2-2
番号付きリスト
1. リスト1
2. リスト2
1. リスト2-1
2. リスト2-2
- リスト1
- リスト2
- リスト2-1
- リスト2-2
インラインスタイル
*イタリック*\
**太字**\
***太字イタリック***\
~~取り消し線~~\
`inline code`
イタリック
太字
太字イタリック
取り消し線
inline code
また、文の末尾に\
を記述することで、改行されます。
テキストリンク
[リンク](https://alg.tus-ricora.com)
画像
![RICORAのロゴ](./images/ricora.svg)
テーブル
| ヘッダ1 | ヘッダ2 | ヘッダ3 |
| ------- | ------- | ------- |
| 1-1 | 1-2 | 1-3 |
| 2-1 | 2-2 | 2-3 |
ヘッダ1 | ヘッダ2 | ヘッダ3 |
---|---|---|
1-1 | 1-2 | 1-3 |
2-1 | 2-2 | 2-3 |
テーブルのスタイル
| 左揃え | 中央揃え | 右揃え |
| :------ | :------: | -----: |
| 1-1 | 1-2 | 1-3 |
| 2-1 | 2-2 | 2-3 |
左揃え | 中央揃え | 右揃え |
---|---|---|
1-1 | 1-2 | 1-3 |
2-1 | 2-2 | 2-3 |
コードブロック
コードブロックは、バッククォート3つで囲むことで記述できます。
```javascript
const hello = "Hello, World!";
console.log(hello);
```
const hello = "Hello, World!";
console.log(hello);
最初のバッククォート3つの後に、言語名を指定することで、シンタックスハイライトが適用されます。シンタックスハイライトにはShikiを使用しています。シンタックスハイライトをサポートしている言語については、Shikiのドキュメントを参照してください。
言語名の後には、半角スペース区切りで属性を指定できます。以下に利用可能な属性の例を示します。
タイトル付きコードブロック
```javascript title=app.js
const hello = "Hello, World!";
console.log(hello);
```
const hello = "Hello, World!";
console.log(hello);
行番号付きコードブロック
```javascript showLineNumbers
const hello = "Hello, World!";
console.log(hello);
```
const hello = "Hello, World!";
console.log(hello);
行ハイライト
```javascript {1-3, 5}
const hello = "Hello,"
const world = "World!";
console.log(hello, world);
// 4行目はハイライトされない
console.log("Hello, MDX!");
```
const hello = "Hello,"
const world = "World!";
console.log(hello, world);
// 4行目はハイライトされない
console.log("Hello, MDX!");
Diff表示
```javascript diff
- const hello = "Hello, World!";
+ const hello = "Hello, MDX!";
console.log(hello);
```
const hello = "Hello, World!";
const hello = "Hello, MDX!";
console.log(hello);
複数の属性を指定
タイトルや行番号、Diff表示など、複数の属性を同時に指定できます。
```javascript diff showLineNumbers {2} title="app.js"
- const hello = "Hello, World!";
+ const hello = "Hello, MDX!";
console.log(hello);
```
const hello = "Hello, World!";
const hello = "Hello, MDX!";
console.log(hello);
数式
数式は、LaTeX形式で記述できます。数式のレンダリングにはKaTeXを使用しています。
使用できるLaTeXのコマンドについては、KaTeXのドキュメントを参照してください。
数式ブロック
$$
\forall \epsilon > 0, \exists \delta > 0 \text{ s.t. } |x - a| < \delta \Rightarrow |f(x) - b| < \epsilon
$$
インライン数式
$a^2 + b^2 = c^2$
引用
> 引用文
引用文
脚注
これは脚注です[^1]。
[^1]: 脚注の内容
これは脚注です1。
区切り線
---
コメントアウト
{/* コメントアウト */}
フロントマター
フロントマターは、MDXファイルの先頭に記述するYAML形式のメタデータです。フロントマターは、記事のタイトルやアイコン、公開日時、更新日時などの情報を指定するために使用されます。
フロントマターは、ファイル先頭の---
で囲まれた部分に記述します。以下にフロントマターの例を示します。
---
draft: false
title: 記事のタイトル
icon: fluent-emoji:party-popper
date: 2024-02-16T00:00:00+09:00
lastmod: 2024-02-16T00:00:00+09:00
categories:
- news
tags:
- 雑記
---
利用可能なプロパティ
以下に利用可能なフロントマターのプロパティを示します。
プロパティ名 | 必須 | 与えられる値 | 説明 |
---|---|---|---|
draft | ❌ | true またはfalse | 記事を下書きとして扱うかどうかを指定します。true の場合、記事は下書きとして扱われ、公開されません。 |
title | ⭕ | 任意の文字列 | 記事のタイトルを指定します。 |
icon | ⭕ | Iconifyで定義されているアイコン名 | 記事のアイコンを指定します。指定するアイコンは、Icônesから検索すると便利です。 |
date | ⭕ | 日付 | 記事の公開日時を指定します。 |
lastmod | ❌ | 日付 | 記事の最終更新日時を指定します。 |
categories | ❌ | カテゴリ名の配列 | 記事のカテゴリを指定します。 |
tags | ❌ | タグ名の配列 | 記事のタグを指定します。 |
カテゴリ
カテゴリは、記事の分類のために使用されます。カテゴリは、categories
プロパティに配列で指定します。
現在利用可能なカテゴリは、以下の通りです。
activities
: 活動記録news
: お知らせworks
: 作品紹介
利用可能なカテゴリは、src/content/categoriesにて定義されています。
タグ
タグは、記事のキーワードを指定するために使用されます。タグは、tags
プロパティに配列で指定します。
タグは、src/content/tagsにて定義されているタグのIDもしくは、任意の文字列を指定できます。
src/content/tagsにて定義されていないタグを指定した場合、その指定したタグ名(文字列)が新たにタグとして登録されます。このとき、指定したタグ名(文字列)が新たに登録されたタグのID兼タイトルとなります。IDとタイトルを別々にしたい場合は、src/content/tagsにて新たにタグを定義してください。このとき、新たに作成したYAMLファイルのファイル名がタグのIDとなり、YAMLファイル内のtitle
プロパティの値がタグのタイトルとなります。
以下に、IDがrust
でタイトルがRust
のタグを定義する例を示します。
title: Rust
コールアウト
引用の先頭の行に、[!type] title
という形式の記述をすることで、コールアウトを表示できます。
ただし、type
はコールアウトの種類を表し、title
はコールアウトのタイトルを表します。また、title
は省略できます。
コールアウトの種類
> [!note]
> コールアウト
コールアウト
> [!info]
> コールアウト
コールアウト
> [!abstract]
> コールアウト
コールアウト
> [!tldl]
> コールアウト
コールアウト
> [!todo]
> コールアウト
コールアウト
> [!tip]
> コールアウト
コールアウト
> [!success]
> コールアウト
コールアウト
> [!question]
> コールアウト
コールアウト
> [!warning]
> コールアウト
コールアウト
> [!caution]
> コールアウト
コールアウト
> [!failure]
> コールアウト
コールアウト
> [!danger]
> コールアウト
コールアウト
> [!error]
> コールアウト
コールアウト
> [!bug]
> コールアウト
コールアウト
> [!important]
> コールアウト
コールアウト
> [!example]
> コールアウト
コールアウト
> [!quote]
> コールアウト
コールアウト
また、未定義なコールアウトを使用した場合、それはNoteとして表示されます。
> [!undefined]
> 未定義のコールアウト
未定義のコールアウト
タイトル付きコールアウト
任意のコールアウトには、タイトルを付けることができます。
> [!note] 重要ポイント
> This is a note.
This is a note.
タイトルには、任意のインライン要素を含めることができます。
> [!note] $a=1$のとき`true`となる*理由*
> This is a note.
true
となる理由 This is a note.
ネストしたコールアウト
コールアウトはネストできます。
> [!note]
> コールアウト
> > [!info]
> > ネストしたコールアウト
> > > [!warning]
> > > さらにネストしたコールアウト
コールアウト
ネストしたコールアウト
さらにネストしたコールアウト
また、コールアウト内には他のブロック要素を含めることができます。
> [!note]
> ここは**コールアウト**の*中身*です。
> ```js title=app.js showLineNumbers
> const hello = "Hello, World!";
> console.log(hello);
> ```
> - リスト1
> - リスト2
ここはコールアウトの中身です。
const hello = "Hello, World!";
console.log(hello);
- リスト1
- リスト2
リンクカード
URLを直接そのまま記述することで、リンクカードを表示できます。
また、URLの上下には空行を入れてください。空行のない場合、リンクカードではなくURLがそのまま表示されます。
https://github.com/ricora
ただし、埋め込みに対応しているURLの場合は、埋め込みが優先して表示されます。
埋め込みに対応しているURLでリンクカードを表示したい場合は、以下のようにLinkCard
コンポーネントを使用してください。
import { LinkCard } from "@/components/Elements/LinkCard"
<LinkCard href="https://github.com/ricora" />
埋め込み
oEmbedに対応しているURLを以下のように記述することで、埋め込みを表示できます。リンクカードと同様に、URLの上下には空行を入れてください。
https://www.youtube.com/watch?v=Gy5vAs_jQSo
以下に対応しているウェブサイトの例を示します。これら以外でも、oEmbedに対応しているウェブサイトであれば、埋め込みが表示されます。
YouTube
Speaker Deck
Docswell
Google Slides
Spotify
Adventar
JSX
MDXでは、ファイル内にJSXを記述できます。
JSX(JavaScript XML)は、XMLライクなJavaScriptの拡張構文です。
JSXを用いると、JavaScriptのコード内にHTMLタグのような構文が埋め込み可能となり、宣言的にUIを記述できます。 一般的にはReactやSolidJSなどのフレームワークで使用されますが、MDX内でも使用できます。
本サイトでは、SolidJSとAstroを使用しているため、SolidJSもしくはAstroのコンポーネントをインポートして使用することができます。
その他に、div
やspan
といったHTMLタグも使用可能です。
ただし、これらJSX要素は最終的にp
タグ内にレンダリングされることに注意してください。
詳しくは、以下のリンクを参照してください。
以下に、カスタムコンポーネントCounter
を./Counter.tsx
に作成し、それをMDX内でインポートして使用する例を示します。
import { Counter } from "./Counter"
<Counter client:visible />
import { createSignal, type Component } from "solid-js"
export const Counter: Component = () => {
const [count, setCount] = createSignal(0)
const increment = () => setCount((prev) => prev + 1)
const decrement = () => setCount((prev) => prev - 1)
return (
<div class="space-x-2">
<div class="p-2">Count: {count()}</div>
<button onClick={increment} class="rounded border p-2 font-mono">
+1
</button>
<button onClick={decrement} class="rounded border p-2 font-mono">
-1
</button>
</div>
)
}
インタラクティブなコンポーネントを使用する場合は、client:*
ディレクティブを適用することを忘れないでください。
client:*
ディレクティブを適用することで、クライアントサイドでコンポーネントのJavaScriptが実行されるようになります。これにより、インタラクティブな操作が可能になります。
利用可能なclient:*
ディレクティブについては、以下のリンクを参照してください。
また、任意のJSX要素の中ではMDX記法を使用できます。
{/* prettier-ignore */}
<div class="border border-blue-6 rounded-lg bg-blue-a4 p-4">
- list 1
- list 2
> Done is better than perfect.
</div>
- list 1
- list 2
Done is better than perfect.
HTML要素内でMDX記法を使用する場合、Prettierのフォーマットを無効化することを推奨します。
Prettierは、HTML要素内の文字列を改行等を無視して1行にまとめるため、不正なフォーマットとなることがあります。そのため、HTML要素内でMDX記法を使用する場合は、/* prettier-ignore */
を使用してPrettierのフォーマットを無効化してください。
詳しくは、MDXの公式ドキュメントを参照してください。
JavaScript式
MDXでは、ファイル内にJavaScript式を記述できます。
{}
で囲まれた部分は、JavaScript式として評価されます。
1 + 1 = {1 + 1}
1 + 1 = 2
詳しくは、MDXの公式ドキュメントを参照してください。
-
脚注の内容 ↩