本サイトで利用可能なMDX記法一覧

このページでは、本サイトで使用しているMDXの記法について説明します。

MDXは、Markdownをベースとしつつ、JSXをMarkdown内に記述することを可能としたマークアップ言語です。一部利用できないMarkdown(CommonMark)の記法がありますが、概ねCommonMarkに準拠しています。

また、本サイトではGitHub Flavored Markdown(GFM)で定義されている機能も利用できます。GFMCommonMarkのスーパーセットであり、URLの自動リンク化や脚注、打ち消し線や表組みなど、CommonMarkにはない機能を提供しています。

さらに、本サイト独自の拡張機能として、コールアウトやリンクカード、埋め込みなどの機能を提供しています。

以下に利用可能なMDX記法を示します。

見出し

# 見出し1
## 見出し2
### 見出し3
#### 見出し4
##### 見出し5
###### 見出し6

見出し1

見出し2

見出し3

見出し4

見出し5
見出し6
< >>
見出し1は使用しない

アクセシビリティの観点から、見出しはレベル2から始めてください。

これは、慣例的に見出し1は文書のタイトルとして使用されるためです。本サイトでは、文書のタイトルはフロントマターで指定するため、見出し1を使用することはありません。

見出し1, 2, …はそれぞれHTMLのh1, h2, …として最終的に表示されます。したがって、MDX内でもHTMLの慣例に則り、以下のリンクに示されているように見出し1は1つのページに1つだけ使用することが推奨されます。

< >>
見出し5, 6の使用は推奨されない

見出し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. リスト1
  2. リスト2
    1. リスト2-1
    2. リスト2-2

インラインスタイル

*イタリック*\
**太字**\
***太字イタリック***\
~~取り消し線~~\
`inline code`

イタリック
太字
太字イタリック
取り消し線
inline code

また、文の末尾に\を記述することで、改行されます。

テキストリンク

[リンク](https://alg.tus-ricora.com)

画像

![RICORAのロゴ](./images/ricora.svg)

RICORAのロゴ

テーブル

| ヘッダ1 | ヘッダ2 | ヘッダ3 |
| ------- | ------- | ------- |
| 1-1     | 1-2     | 1-3     |
| 2-1     | 2-2     | 2-3     |
ヘッダ1ヘッダ2ヘッダ3
1-11-21-3
2-12-22-3

テーブルのスタイル

| 左揃え  | 中央揃え | 右揃え |
| :------ | :------: | -----: |
| 1-1     | 1-2      | 1-3    |
| 2-1     | 2-2      | 2-3    |
左揃え中央揃え右揃え
1-11-21-3
2-12-22-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);
```
app.js
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);
```
app.js
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
$$
ϵ>0,δ>0 s.t. xa<δf(x)b<ϵ\forall \epsilon > 0, \exists \delta > 0 \text{ s.t. } |x - a| < \delta \Rightarrow |f(x) - b| < \epsilon

インライン数式

$a^2 + b^2 = c^2$

a2+b2=c2a^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:
  - 雑記
---

利用可能なプロパティ

以下に利用可能なフロントマターのプロパティを示します。

プロパティ名必須与えられる値説明
drafttrueまたはfalse記事を下書きとして扱うかどうかを指定します。trueの場合、記事は下書きとして扱われ、公開されません。
title任意の文字列記事のタイトルを指定します。
iconIconifyで定義されているアイコン名記事のアイコンを指定します。指定するアイコンは、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のタグを定義する例を示します。

src/content/tags/rust.yaml
title: Rust

コールアウト

引用の先頭の行に、[!type] titleという形式の記述をすることで、コールアウトを表示できます。

ただし、typeはコールアウトの種類を表し、titleはコールアウトのタイトルを表します。また、titleは省略できます。

コールアウトの種類

> [!note]
> コールアウト
< >>
Note

コールアウト

> [!info]
> コールアウト
< >>
Info

コールアウト

> [!abstract]
> コールアウト
< >>
Abstract

コールアウト

> [!tldl]
> コールアウト
< >>
TL;DR

コールアウト

> [!todo]
> コールアウト
< >>
ToDo

コールアウト

> [!tip]
> コールアウト
< >>
Tip

コールアウト

> [!success]
> コールアウト
< >>
Success

コールアウト

> [!question]
> コールアウト
< >>
Question

コールアウト

> [!warning]
> コールアウト
< >>
Warning

コールアウト

> [!caution]
> コールアウト
< >>
Caution

コールアウト

> [!failure]
> コールアウト
< >>
Failure

コールアウト

> [!danger]
> コールアウト
< >>
Danger

コールアウト

> [!error]
> コールアウト
< >>
Error

コールアウト

> [!bug]
> コールアウト
< >>
Bug

コールアウト

> [!important]
> コールアウト
< >>
Important

コールアウト

> [!example]
> コールアウト
< >>
Example

コールアウト

> [!quote]
> コールアウト
< >>
Quote

コールアウト

また、未定義なコールアウトを使用した場合、それはNoteとして表示されます。

> [!undefined]
> 未定義のコールアウト
< >>
Note

未定義のコールアウト

タイトル付きコールアウト

任意のコールアウトには、タイトルを付けることができます。

> [!note] 重要ポイント
> This is a note.
< >>
重要ポイント

This is a note.

タイトルには、任意のインライン要素を含めることができます。

> [!note] $a=1$のとき`true`となる*理由*
> This is a note.
< >>
a=1a=1のときtrueとなる理由

This is a note.

ネストしたコールアウト

コールアウトはネストできます。

> [!note]
> コールアウト
> > [!info]
> > ネストしたコールアウト
> > > [!warning]
> > > さらにネストしたコールアウト
< >>
Note

コールアウト

< >>
Info

ネストしたコールアウト

< >>
Warning

さらにネストしたコールアウト

また、コールアウト内には他のブロック要素を含めることができます。

> [!note]
> ここは**コールアウト***中身*です。
> ```js title=app.js showLineNumbers
> const hello = "Hello, World!";
> console.log(hello);
> ```
> - リスト1
> - リスト2
< >>
Note

ここはコールアウト中身です。

app.js
const hello = "Hello, World!";
console.log(hello);
  • リスト1
  • リスト2

リンクカード

URLを直接そのまま記述することで、リンクカードを表示できます。

また、URLの上下には空行を入れてください。空行のない場合、リンクカードではなくURLがそのまま表示されます。

ただし、埋め込みに対応している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とは

JSX(JavaScript XML)は、XMLライクなJavaScriptの拡張構文です。

JSXを用いると、JavaScriptのコード内にHTMLタグのような構文が埋め込み可能となり、宣言的にUIを記述できます。 一般的にはReactSolidJSなどのフレームワークで使用されますが、MDX内でも使用できます。

本サイトでは、SolidJSAstroを使用しているため、SolidJSもしくはAstroのコンポーネントをインポートして使用することができます。 その他に、divspanといったHTMLタグも使用可能です。 ただし、これらJSX要素は最終的にpタグ内にレンダリングされることに注意してください。

詳しくは、以下のリンクを参照してください。

以下に、カスタムコンポーネントCounter./Counter.tsxに作成し、それをMDX内でインポートして使用する例を示します。

import { Counter } from "./Counter"

<Counter client:visible />
Counter.tsx
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>
  )
}
Count: 0
< >>
インタラクティブなコンポーネントの使用

インタラクティブなコンポーネントを使用する場合は、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.

< >>
Prettierを無効化する

HTML要素内でMDX記法を使用する場合、Prettierのフォーマットを無効化することを推奨します。

Prettierは、HTML要素内の文字列を改行等を無視して1行にまとめるため、不正なフォーマットとなることがあります。そのため、HTML要素内でMDX記法を使用する場合は、/* prettier-ignore */を使用してPrettierのフォーマットを無効化してください。

詳しくは、MDXの公式ドキュメントを参照してください。

JavaScript式

MDXでは、ファイル内にJavaScript式を記述できます。

{}で囲まれた部分は、JavaScript式として評価されます。

1 + 1 = {1 + 1}

1 + 1 = 2

詳しくは、MDXの公式ドキュメントを参照してください。

脚注
  1. 脚注の内容