Markdownとアプリによる自由闊達なコラボレーションツールの「cattaz」を作った

[FUJITSU Advent Calendar 2017](https://qiita.com/advent-calendar/2017/fujitsu)の14日目です。

## 作った

Markdownとアプリによる自由闊達なコラボレーションツールの「cattaz」を2017年11月16日にOSSとして公開しました。[日本語の紹介ページ](http://cattaz.io/index-ja.html)、[英語の紹介ページ](http://cattaz.io/)、[GitHubのリポジトリ](https://github.com/FujitsuLaboratories/cattaz)、[デモ](http://cattaz.io/build/)、[日本語ドキュメント](http://cattaz.io/build/#/doc/ja/index)、[英語ドキュメント](http://cattaz.io/build/#/doc/index)などがリンクです。どういうソフトウェアなのかの説明は紹介ページにある動画が最も分かりやすいと思います。

この記事では上記のリンク先に書かれていないことを書いていこうと思います。

## 経緯

そもそもなぜ作ったのか。

会社員ならば会議というものを頻度の差はあれ誰もがやっていることで、会議の議事録をWiki等で書くこともよくあることかと思います。

スクラム開発の振り返りでKPTを行う際に、一般的にホワイトボードやポストイットなどのアナログなツールを使ってまとめていきます。ホワイトボードであればKPTの表を書くのは簡単ですが、ホワイトボードやポストイットを使う場合には記録性や検索性にすぐれません。

一方WikiではKPTの表を書くのはそれほど簡単ではありません。簡単に表にはできないので、表を使わずにMarkdownの入れ子リストで我慢していたのではないでしょうか。まあこれでも実用上は問題ありません。

```md
* Keep
  * keep1
  * keep2
* Problem
  * problem1
  * problem2
* Try
  * try1
  * try2
```

KPTくらいなら回避策はありますが、マインドマップを作ろうとするとWikiの書式ではさすがに困難です。仕方がないのでマインドマップ用の別のツールでマインドマップを作り、ファイルサーバにアップロードをしてWikiからリンクを張るという運用になります。

いろいろなツールを行き来しなければならず、議事録の本体であるWikiだけで完結できないだろうかと模索しました。

## 影響を受けたソフトウェア

Markdownに拡張を行っているソフトウェアはいくつか存在し、本ソフトウェアを作るときに私たちが影響を受けたのは以下のソフトです。

### R Markdown

[R Markdown](http://rmarkdown.rstudio.com/)は、Markdownのfenced code blockにRやPythonなどでプログラムを記述すると、そのプログラムの実行結果を文書中に表示してくれます。

Markdown単体にはデータの可視化機能がないため、文書中で可視化されたデータを表示したいときには、従来であれば可視化した結果を画像ファイルにしてサーバにアップロードし、その画像のアドレスをMarkdownから参照することが一般的でした。その場合、データや可視化方法を修正すると、画像の再生成、画像のアップロード、画像アドレスの更新、といった本質ではない作業が必要となります。

R MarkdownではMarkdown中にプログラムを埋め込めるため、Markdown単体で可視化が完結します。データの可視化パラメータを修正しながら、その可視化結果を文章で記述するといった作業をエディタから離れずに継続することができます。

### HackMD

[HackMD](https://hackmd.io/)は、オンライン上でMarkdownを共同編集できるソフトウェアで、Markdownのfenced code blockに[数式](https://hackmd.io/features#mathjax)や[UML](https://hackmd.io/features#uml-diagrams)を記述するとそれらがリアルタイムにプレビューエリアに表示されます。

ブラウザだけで完結でき、なおかつ共同編集機能も付いているため、とても使いやすいものとなっています。

## コンセプト

### テキスト主体

R MarkdownもHackMDもテキストであるMarkdownを主体にしています。テキストが主体であると、バージョン管理との相性も良く、他のソフトウェアとの連携もしやすくなります。本ソフトでもテキスト主体のコンセプトを踏襲することにしました。

### 双方向性

R MarkdownもHackMDもMarkdown中の編集はレンダリング結果に反映されますが、逆にレンダリングされた結果からソースに反映させることはできません。編集が一方向のみです。古いたとえを出すと、HTMLオーサリングソフトのホームページビルダーはプレビュー画面で編集するとHTMLソースにも反映され、編集が双方向でした。

Markdown自体は単純な文法なので一方向のみの編集でも事足りることが多いです。例えばHackMDでUMLを記述しているときにプレビュー画面でもUMLが編集できれば便利だと考えました。それと同様にプレビュー画面でも編集が可能となる双方向性を導入することにしました。

### アプリケーションを追加可能

ユーザが独自にアプリケーションを開発できるようにし、ユーザが自身の要求を満たせられるような設計にしました。

アプリケーションがMarkdownの文法を意識する必要をなくすことで、将来的にMarkdownから別のマークアップ言語に切り替わってもアプリケーションが利用できるようにしました。またアプリケーション独自のフォーマットで任意にデータを保存できるようにするため、Markdownではfenced code blockにアプリケーションのデータを格納することにしました。

## コンセプトの組み合わせによる効果

### 通信機能の実装なしで通信可能

アプリケーションの状態がテキストとしてMarkdownに埋め込まれ、そのMarkdownはプラットフォーム側で同期されます。そのため、あるユーザがアプリケーションで操作すると、その操作の結果の状態がそのユーザの画面にも反映されます。

例えば、あるユーザがカンバンでタスクをドラッグアンドドロップして移動させたら、他のユーザの画面でもタスクが移動します。しかしカンバンアプリケーションは通信に関するロジックを一切実装せずにそれが実現できています。オセロアプリケーションも同様です。

### 文字列の入出力

データを扱う一般的なアプリケーションでは、ファイルやネットワークを使うことになる為、IOに起因する例外を配慮しなければなりません。例外処理は複雑なもので、小規模なアプリケーションでは本筋のロジックよりも例外処理のほうが多いことも起こりえるほどです。

アプリケーションにはそれぞれのロジックに注力してもらいたいので、プラットフォーム側で通信やMarkdownパージングを行った結果の文字列をアプリケーションに渡すようにしました。そのためアプリケーションが実装すべき処理は、入力された文字列をパーズする処理、アプリケーション自体の処理、アプリケーションの状態を文字列に変換する処理、を記述するのみでよくなります。

## 今後の要検討項目

Markdownのパーズ部分や、Markdownとアプリケーションの橋渡し部分しかまだ検討や実装がなされていません。今後は以下のことを検討していく予定です。

* アプリケーション間での通信
  * 現在は一つのfenced code blockから一つのアプリケーションが実行されるだけで、アプリケーション間では通信をすることができません。アプリケーションごとに単一の機能を提供し、ユーザが自由にアプリケーションを組み合わせられるようにしたいです。
* アプリのデーモン
  * 現状ではユーザアプリケーションは各ブラウザ内で動いているのみです。そのためブラウザを開いていなければユーザアプリケーションが動作してデータを更新することができません。アプリケーションによっては定期的に外部からデータを取得して内容を書き換えるといった用途もあるはずで、そのためにはユーザロジックがデーモン的に動作している必要があります。
* パーシステンス
  * 現在はサーバ上のデータをストレージ等に保存しておらず、サーバを立ち上げ直すとデータが消えてしまいます。ブラウザ側にもデータが残っているのでサーバの再起動の前後でブラウザが立ち上がっていればデータが再登録されはしますが、サーバでデータを保存するほうが当然ながら望ましいです。
* セキュリティ
  * まだユーザ認証すらない状態です。セキュリティ機能は実運用に際しては必須となります。