Markdown対応GitバックエンドのWikiシステム

# Markdown対応GitバックエンドのWikiシステム(pregit)

Git Advent Calendar 19日目から続いているような記事です。
[PythonでGitのサーバーを作った話 - Qiita Git Advent Calendar 19日目](https://qiita.com/beckorz/items/a6ca1ad2b73643e844c8)

![favicon_200.png](https://qiita-image-store.s3.amazonaws.com/0/325393/69a2b0d6-595e-284d-8e9d-654c82c147e1.png)

～ Python3 で previm + Git + wiki な pregit を作った話と紹介 ～

## 作った経緯
私はVimmerという事もあり、Vim向けのMarkdownプレビューのprevimプラグインを自分用に若干カスタマイズして作っておりました。
基本的には脳内プレビューで済みますが自分で書き溜めているTipsやドキュメント等を他人に見せる際に、サーバー的に動作するプレビューサイトが欲しいなと思ったり、Markdown文書をprevimでプレビューした物をwkhtmltopdfでPDF出力しながら他人に渡したりしてたのでその手間自体が面倒だなと思いながら使っておりました。
そんな気持ちでいると、「previmのページ自体を他人に見せたいな」と思い始めました。出来れば「gitバックエンドなシステムで」となりました。
そこから世の中にあるMarkdownの方言、GitHubクローンを触りながら、やっぱり previm + Git + wiki な物を作りたいなとふつふつと思いを貯めこんでいき・・・どれも違うな？と思いながら・・・作り始めました。

これだけを聞くと、それなんてGollum? と言う人がいると思いますが・・・作りました。


## エビデンス
[pregitリポジトリ](https://github.com/beckorz/pregit)

と、イメージ
![pregit_ss.png](https://qiita-image-store.s3.amazonaws.com/0/325393/d3148361-5e64-2a0c-dd70-c782b3c9d862.png)

デモ用サイトなどどこかで稼働させた方が良いんでしょうが、表立ったとこに配置するのが面倒で今ソースとイメージだけ。

--------------

(READMEを参照ください。と言いたいところですが、一応日本語でも説明。)


## 用途
- ナレッジベース
- 議事録
- 操作マニュアル
- 個人用途、複数人での使用
- クラウド環境を利用できない、オンプレミス環境または、ローカル環境でもMarkdownプレビューを使いたい方。
- ローカル環境でもMarkdownプレビューを使いたい方


## 機能
- Gitリポジトリに対応しています。`git clone`, `git push`.
- Gitリポジトリではない生のテキストファイルのディレクトリ(フォルダ)にも対応しています。
- Markdownフォーマットに対応しています。
    - GFM風なCommonMarkに対応しています。細かい対応は[こちら](https://github.com/beckorz/previm)を参考下さい。
- クロスプラットフォームで動作します。(Win/Linux/Mac)
- Webサーバーを内蔵しており、リバースプロキシー上でも動作します。
    - SSLをサポートしております。(Apache, nginx etc).
- PDFダウンロード機能
- 生ファイルのダウンロード機能


## 必要な物
- Python 3 が必要(Python 3.5 以降)
- Gitクライアントが必要(任意)
- wkhtmltopdf (任意)


### Python依存関係をインストール

Pythonで他に使うモジュールをインストールします。

- chardet

    ```sh
    pip install chardet
    ```

- Flask

    ```sh
    pip install flask
    ```

もしくは、

```sh
pip install -r requirements.txt
```

## インストール
1. Gitクライアントをインストール(任意)
2. Python 3 をインストール
3. Pythonの必要モジュールをインストール
4. `config.ini` で設定します。
    - サンプルディレクトリを作成するbatを用意しています。(現在Windows向けに)
        - `initial_sample_repo.bat` を実行してください
5. サーバーを開始

    ```sh
    python app.py
    ```

6. ブラウザで、 `http://localhost:5000/` を開きます。

もし、ファイルを修正したい場合は、 `git clone`, `git push`して修正してください。[^raw]

[^raw]: Rawタイプで設定している場合は、直接修正する事で反映させれますが。


## 注意
- Gitのリポジトリはベアリポジトリに対応しています。(cloneする分にはベアでなくでもいけるみたいですが。pushする際にエラーになったはず)
- PDF出力時には、 [wkhtmltopdf](https://wkhtmltopdf.org) が必要です。デスクトップ環境が無い場合は、環境構築が大変そうですが。


## 対応ブラウザ
IE11, Edge, Firefox, Chrome, Safari


## カスタマイズ
見た目を弄る場合は以下辺りを修正してください。

- /static/css/\*


## 謝辞(参考、利用にした物)
- [previm](http://github.com/previm/previm/)
    - vimのmarkdownプレビュー用プラグイン。これを使ったのが一番のきっかけです。作者様ありがとうございます。
- [Gollum](https://github.com/gollum/gollum)
    - gitバックエンドのWikiシステムとしてはこれを参考にしています。使ってみると分かりますが、bareなGitリポジトリ上で動いていないのですね。
- [gitprep](http://gitprep.yukikimoto.com/)
    - Perl製GitHubクローン
- [wkhtmltopdf](https://wkhtmltopdf.org/)
    - QtWebkitエンジンのWebページをPDF(HTML)に出力するツール。Pandocみたいなパーサーを使うよりWebページの見た目でPDFに出力出来る方が、パースロジックの違いを意識しなくて良いのでこれが一番気が楽。
- [Octicons](https://octicons.github.com/)
    - アイコンで使いました。当方デザインセンスが無いので利用しております。
- [Honoka](http://honokak.osaka/)
    - 日本語向けチューニングされた bootstrap。当方デザインセンスが無いので利用しております。

他にも色々なGitHubクローンや、Markdownパーサー、Markdownプレビュー等は触れるものは触って来たのですが、どれも一長一短でお手軽さがありませんでした。


## 開発時に意識した事
- どこかのサーバー上でも動かせれるし、ローカルPCでも動かせれるように。
- 依存性を少なくクロスプラットフォームで動作させる事。
  動作上Pythonには依存してしまっておりますが、バージョン管理不要という事であれば、Gitクライアントにも依存しません。Gitのリポジトリを作らず生のテキストファイルを格納したディレクトリ構成でも使えるようにしております。[^Raw2]
  [^Raw2]: そうすると直接テキストファイルを修正すればリアルタイムプレビューがし易くなりますが、Gitの良いところが使えないので一長一短。
- Gitクライアントさえあれば、pushする事でwikiのように誰でも編集出来る事。
- 本家previmに無いリッチな機能 [beckorz/previm](https://github.com/beckorz/previm/)
    - よりよいTask listの見た目に
        - markdown-it-checkbox ではなく、 markdown-it-task-lists を採用
    - `<kbd>` タグの利用
    - TOC生成(PDFにも)
    - wkhtmltopdf のPDF出力向けに `print`のメディアクエリ対応
    - 外部リンクの場合、別タブで開く機能
    - Emoji対応
    - 画像サムネイル対応(Fancybox風)
    - Mac風Dropshadowな画像css
- previm のリアルタイムプレビューをサーバー版でも一応動作
- 検索機能や、編集機能は、ローカル側で行う為、サーバー側では持たないようにした
- 画像は相対パス等で指定できます。同梱サンプルを参考下さい。


## まだ足りない事
- 実際のプレビューページがスマートフォン向けのサイズに最適化されていません。
- マルチリポジトリ構成
- 数式対応
- ユーザー毎のアクセス権、認証の仕組み
- 動作させ易いように dockerfile, dockerimage 準備
- scrapbox のように、独自cssを導入し易い仕組み
- 更新の通知機能
- 色々未実装


## その他
- wkhtmltopdf を使っているのは、ブラウザ内蔵のPDF出力や、OS標準の仮想PDFプリンターを使っても、ヘッダー・フッターが思ったような出力にならない、目次が出力出来ない等微妙だった為です。
- previm自体は、軽量を好んでjQueryや、MathJaxを導入していない経緯があります。[Add TeX mathematical notation support via MathJax. · Pull Request #41 · previm/previm](https://github.com/previm/previm/pull/41)
    - pregitでは今後追加できる仕組みにしようと思っています。
- Gitのサーバー部分だけの[git-server.py](https://github.com/beckorz/git-server)というものを作りました。というか、元々Python2のコードをPython3で書いてるだけですが参考になれば。
- 名前は、previm を参考にしましたが、pregit は微妙かなと思っています。名前募集中
- VimConf 2018に参加させていただき、channel機能を使ってVimプラグインのみで動作させれそうな期待を持ちました。(Blob型も扱えれば・・・そしてVimはエディタの枠を超えて、そしてサーバーへ)


## おススメな使い方
previmでも使えますが、もしWindows環境なクライアントOSでOutlook等のメーラーを使ってるようだったら、コードハイライトした物を相手に送れます[^CodeHighlightMail]

[^CodeHighlightMail]: Microsoftに親和性が高いIE、Edgeなブラウザであれば、プレビューされたページから文章をコピーしてメーラーの編集画面に張り付ければ、リッチテキスト(HTML)形式でコードハイライトした物を張り付けれます。

![CodeHighlight_on_Mailer.png](https://qiita-image-store.s3.amazonaws.com/0/325393/164f1cc5-e239-5411-fe88-540d21f6d702.png)


## Thanks
- previm の作者、メンテナー様達
- 動作確認で触っていただいて感想をいただいた方