🐕

【deno-gfm】DenoでMarkdown2HTML

2023/01/15に公開

以前、Denoを使ってマークダウンベースのブログを作るための方法を紹介しました。
https://zenn.dev/k41531/articles/9897a0f8fce1b3
今回は、deno-gfmというGitHubスタイルでMarkdownをレンダリングするためのライブラリの紹介です。上記の記事で使ったライブラリdeno_blogやFreshのWebサイトでもMarkdownを表示するために使われています。
https://github.com/denoland/deno-gfm

deno-gfmの使い方は非常に簡単で、リポジトリの方にもUsageにわかりやすいサンプルコードが載せてあります。

Markdown to HTML

サンプルコードを少し変更しただけですが、マークダウンファイルからhtmlファイルに変換する簡単なCLIアプリを作ってみることにします。

プロジェクトの作成

mkdir md2html
cd md2html

コード

main.ts

import { CSS, render } from "https://deno.land/x/gfm/mod.ts";

const input_file_name = Deno.args[0];
const output_file_name = Deno.args[1];

const markdown = await Deno.readTextFile(input_file_name);
const body = render(markdown);

const html = `
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
      main {
        max-width: 800px;
        margin: 0 auto;
      }
      ${CSS}
    </style>
  </head>
  <body>
    <main data-color-mode="light" data-light-theme="light" data-dark-theme="dark" class="markdown-body">
      ${body}
    </main>
  </body>
</html>
`;

await Deno.writeTextFile(output_file_name, html);

import { CSS, render } from "https://deno.land/x/gfm/mod.ts";でgfmというモジュールからCSSとレンダーをインポートしています。

renderは、マークダウンで書かれた文字列を、htmlタグを使ったものに変換してくれます。

CSSは、GitHub Flavoredのデザインにするためのスタイルシートです。
もし、他のデザインにしたい場合は、これを使わずに別のスタイルシートや、自らデザインしたスタイルシートを使たり、一部だけデザインを変更することもできます。

マークダウンファイル

変換したいマークダウンファイルを用意します。
input.md

# Headers

**Bold**

_Italic_

[Links](https://deno.land)

![Images](https://deno-avatar.deno.dev/avatar/blog.svg)

Lists
- Item 1
- Item 1
- Item 1

> Quotes

`Inline code`

‮```
Code fences
‮```

では、実行してみましょう。

deno run --allow-read --allow-write main.ts input.md output.html

ファイルの読み書きがあるので一部のパーミッションを許可する必要があります。
実行するスクリプト名の後に引数を指定することで、スクリプトに引数を渡すことができます。
参考 : https://deno-ja.vercel.app/manual@v1.9.1/getting_started/command_line_interface#スクリプト引数

出力されたhtmlをブラウザで見てみましょう。

ソースコード(<main>タグの中)は次のようになっています。

<h1 id="headers"><a class="anchor" aria-hidden="true" tabindex="-1" href="[#headers](#headers)"><svg class="octicon octicon-link" viewbox="0 0 16 16" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Headers</h1><p><strong>Bold</strong></p>

<p><em>Italic</em></p>

<p><a href="[https://deno.land](https://deno.land)" rel="noopener noreferrer">Links</a></p>

<p><img src="[https://deno-avatar.deno.dev/avatar/blog.svg](https://deno-avatar.deno.dev/avatar/blog.svg)" alt="Images" /></p>

<p>Lists</p>

<ul>

<li>Item 1</li>

<li>Item 1</li>

<li>Item 1</li>

</ul>

<blockquote>

<p>Quotes</p>

</blockquote>

<p><code>Inline code</code></p>

<pre><code>Code fences</code></pre>

とっても簡単に変換することができました。
これとwebviewなどを組み合わせれば、denoを使ってマークダウンエディタも作れそうです。

コードのシンタックスハイライト

gfmでは、JavaScript、Markdown、HTMLはデフォルトでハイライトされますが、それ以外は標準でサポートされていません。
ただ、別の言語を追加するのも非常に簡単です。

prismjsから使いたい言語をインポートするだけです。

// tyepscript
import "https://esm.sh/prismjs@1.27.0/components/prism-typescript?no-check";
// rust
import "https://esm.sh/prismjs@1.27.0/components/prism-rust?no-check";


その他、使用できる言語は次のリンクにあります。 https://unpkg.com/browse/prismjs@1.27.0/components/

バイナリ化

deno compile --allow-read --allow-write --output md2html main.ts

感想

denoは小さなツールがとても手軽に書けて楽しい。

Discussion