🐙

GitHub 上の Markdown を取得して ASP.NET Core で公開する

2022/06/23に公開

はじめに

Microsoft のドキュメント (MS Docs) は GitHub で管理されており, 編集ボタンをクリックすると該当する Markdown 形式のファイルが表示されます. 例えば記述に不備がある部分を変更してコミットし, プルリクを送れば担当者にチェックされます. 問題なければマージされて, そのままドキュメントのページへと反映されます.

MS のドキュメント例

該当のページ

この仕組みの良いところは, リファレンスを Markdown 形式で作成できるだけでなく, 間違いがあればそれを編集してマージするだけでページへと反映される点です. ライブラリ開発者の皆さんはリファレンス作りが大変かと思いますが、この仕組みを作れれば楽になる?かもしれません.(私は今まで HTML をベタ書きしていたため, ページ1つ作るのに何時間もかかっていました.)

使うもの

  • .NET 6 (コンソールアプリ/ASP.NET Core)
  • Visual Studio 2022 (VS Code でもいいかもしれません. ここは好みですね.)
  • GitHub

ASP.NET Core は HTML/CSS + C# で Web ページを作成できるテンプレートです. あらかじめ Visual Studio の機能で "ASP.NET と Web 開発" のワークロードにチェックをいれてセットアップしておきます.

1. コンソールアプリで試す

Web ページを作成する前に, コンソールアプリで作成してみて, どのようにデータを取得できるかを確認してみます.

1.1 GitHub リポジトリを作る

まずは適当なパブリックリポジトリを作り, Markdown のファイルを置いておきます. 今回は, 私の作成している MinecraftConnection の README.md を読み込ませます.

https://github.com/takunology/MinecraftConnection

1.2 Octokit.net を使用する

Octokit.net は GitHub API を簡単に利用できるようにしたパッケージです. VS でコンソールアプリのプロジェクトを作成し, NuGet から導入します.

NuGet パッケージマネージャーコンソール
install-package Octokit

書き換えたりプライベートリポジトリへアクセスするにはトークンが必要になりますが, 今回はパブリックリポジトリへアクセスかつ読み取りだけですので, 特に何もせずに進められます. トークンを使用した方法はこちらが参考になると思います.

1.3 リポジトリを指定して取得する

リポジトリを参照して中身を読み込むプログラムを書きます.

リポジトリ内のファイル名を取得する
using Octokit;

var repo = "MinecraftConnection";
var author = "takunology";

var github = new GitHubClient(new ProductHeaderValue(repo));
var contents = await github.Repository.Content.GetAllContents(author, repo);
contents.ToList().ForEach(x => Console.WriteLine(x.Name));
実行結果
.gitattributes
LICENSE
MinecraftConnection
PlayerData.txt
README.md
README_JP.md
images

中身を読み込むには GetRawContentByRef() メソッドを使用しますが, この第三引数には読み込みたいファイルパス, 第四引数にはブランチ名を入れる必要があります. ここでは上記のリストの README_JP.md を読み込みたいと思いますので, contents[5].Path としておきます. さらに, 読み込んだ文字列はエンコードしておく必要があります.

最終的なコードはこんな感じになります.

Markdown を取得するプログラム
using Octokit;
using System.Text;

var repo = "MinecraftConnection";
var author = "takunology";
var brunch = "main";

var github = new GitHubClient(new ProductHeaderValue(repo));
var contents = await github.Repository.Content.GetAllContents(author, repo);
var rawContent = await github.Repository.Content.GetRawContentByRef(author, repo, contents[5].Path, brunch);
var text = Encoding.UTF8.GetString(rawContent);

Console.WriteLine(text);
実行結果(一部抜粋)
# MinecraftConnection
<div>
<img src="./images/logo.png" width="350" hspace="0" vspace="10">
</div>

![Nuget (with prereleases)](https://img.shields.io/nuget/vpre/MinecraftConnection)
![Nuget](https://img.shields.io/nuget/dt/MinecraftConnection?color=blue)
![](https://img.shields.io/badge/Minecraft%20Version-1.18~-brightgreen)
![GitHub](https://img.shields.io/github/license/takunology/MinecraftConnection)

MinecraftConnectionはC#を用いてRCONでコマンドを送るためのライブラリです。マイクラによるC#プログラミングの学習や自動化に 応用することができます。バニラ版(通常版)のサーバーだけでなく、プラグインを含むSpigotサーバーでも実行できます。プログラムを実行する前に、RCON 接続が可能な Minecraft サーバーを起動する必要があります。 </br>

# 1. 準備
まずは Minecraft Server ソフトウェアをダウンロードし、任意のゲームディレクトリにて起動します。 `server.properties` とい うサーバ設定ファイルが作成されるので、RCON接続用のパスワードとポート番号を指定し、接続を有効にしてください。

設定例:

'''
rcon.port=25575
rcon.password=minecraft
enable-rcon=true
'''

このようにして GitHub リポジトリのファイルから内容を取得することができます.

1.4 Markdig を使用する

次に, Markdown 形式から HTML 形式へと変換してみます. NuGet から Markdig を導入します.

install-package Markdig

変換自体は簡単で, Markdown クラスの ToHTML() メソッドを挟むだけです.

HTML へ変換するプログラム
using Markdig;

// GitHub に関するコード(省略)

var text = Encoding.UTF8.GetString(rawContent);
var html = Markdown.ToHtml(text);

Console.WriteLine(html);
実行結果 (HTML 出力)
<h1>MinecraftConnection</h1>
<div>
<img src="./images/logo.png" width="350" hspace="0" vspace="10">
</div>
<p><img src="https://img.shields.io/nuget/vpre/MinecraftConnection" alt="Nuget (with prereleases)" />
<img src="https://img.shields.io/nuget/dt/MinecraftConnection?color=blue" alt="Nuget" />
<img src="https://img.shields.io/badge/Minecraft%20Version-1.18%7E-brightgreen" alt="" />
<img src="https://img.shields.io/github/license/takunology/MinecraftConnection" alt="GitHub" /></p>
<p>MinecraftConnectionはC#を用いてRCONでコマンドを送るためのライブラリです。マイクラによるC#プログラミングの学習や自動化に応用することができます。バニラ版(通常版)のサーバーだけでなく、プラグインを含むSpigotサーバーでも実行できます。プログラムを実行する前に、RCON 接続が可能な Minecraft サーバーを起動する必要があります。 </br></p>
<h1>1. 準備</h1>
<p>まずは Minecraft Server ソフトウェアをダウンロードし、任意のゲームディレクトリにて起動します。 <code>server.properties</code> というサーバ設定ファイルが作成されるので、RCON接続用のパスワードとポート番号を指定し、接続を有効にしてください 。</p>
<p>設定例:</p>
<pre><code>rcon.port=25575
rcon.password=minecraft
enable-rcon=true
</code></pre>

ここまでで, GitHub から Markdown を取得して, HTML へ変換するコードが完成しました. 思ったよりも簡単ですね.

2. ASP.NET Core で試す

せっかくなので, Web ページに反映させてみましょう.

2.1 プロジェクト作成とパッケージ導入

ここでは ASP.NET Core で Web サイトを作成します.

あとは手順に従って Web サイト名などを決めてください.

作成できたら手順 1.2, 1.4 と同じように NuGet パッケージマネージャーコンソールから導入します.

NuGet パッケージマネージャーコンソール
install-package Octokit
install-package Markdig

2.2 プログラム作成と動作確認

ソリューションエクスプローラーから Index.cshtml を開きます.

サンプルコードが書かれていますが, 一旦削除して下記のように書き換えます.

Index.cshtml
@page
@using Markdig
@using Octokit
@using System.Text
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="container">
    @{
        var repo = "MinecraftConnection";
        var author = "takunology";
        var brunch = "main";

        var github = new GitHubClient(new ProductHeaderValue(repo));
        var contents = await github.Repository.Content.GetAllContents(author, repo);
        var rawContent = await github.Repository.Content.GetRawContentByRef(author, repo, contents[5].Path, brunch);
        var text = Encoding.UTF8.GetString(rawContent);
        var html = Markdown.ToHtml(text);
    }
    @Html.Raw(@html)
</div>

実行結果 :

Razor 構文によって, @{ } で囲むと C# の記述ができます. HTML に変換した文字列は html 変数に格納されますが, それをそのまま HTML 要素に埋め込んでも, ただの文字列として認識されてしまいます.

なので, @html.Raw() を使用することでタグ要素として読み込み, その内容を反映するように工夫が必要です.

2.3 シンタックスハイライトを導入する

ソースコードの表示などがある場合はシンタックスハイライトがあると見やすいですね. ここでは highlight.js を導入してみます.

ソリューションエクスプローラー内の _Layout.cshtml を開きます.

あとはヘッダーに下記を導入します. ファイル名の部分は好きなスタイルを選択すると良いかと思います. 私は Visual Studio 風のテーマ (vs2015.min.css) を選択してみました.

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/styles/vs2015.min.css">

次にスクリプトを追記します.

<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js"></script>
<script>hljs.highlightAll();</script>

あとは実行するだけです.

だいぶいい感じですね.

2.4 Markdown を編集してみる

ところで, 画像が表示されていなかったと思いますが, これは Markdown 上で GitHub リポジトリの相対パスから参照しているためですね. もし, 画像を表示させたい場合は絶対パスを指定してあげれば良いかと思います.

ちなみに最近 NuGet で README が記述できるようになっていますが, この画像参照の方法が少し特殊です. MS のリファレンスを漁ると, 特定のリンクからしか参照できないようです. なので, GitHub リポジトリ内に置いた画像をそのまま参照することはできません.

そこで raw.githubusercontent.com 経由で取得してみます. 下記のようなリンクを作って, そこと結びつけると画像が表示されます.

https://raw.githubusercontent.com/<author>/<repository>/<branch>/<dir>...

GitHub の Markdown ファイルの画像参照パスを上記のように書き換えて main ブランチにマージしてみます. 完了したら, Web ページを更新してみます.

画像が表示されました~

まとめ

  • Octokit で GitHub リポジトリを参照し, Markdown 形式のファイルを読み込んだ
  • Markdig で Markdown 形式のファイルから HTML ファイルへ変換した
  • ASP.NET Core にて変換したファイルを @html.Raw() でタグ要素として表示できるようにした
  • Markdown の画像参照パスを相対パスから絶対パスに変更すれば画像が表示される
  • ソースコードはいじらなくても, あとは Markdown を編集してマージすれば即座に変更される

これでみんな幸せになれますね. あとは GitHub の要素取得のロジックを適当にいじればサイドバーを作ったり, プルリク送ったり色々できそうですね.

Discussion