【Electronチュートリアル】マークダウンでスライドショーができるアプリを作ろう【第１回】（Electron 6.0.x 対応版）

---

この記事は、2016年8月に投稿した[【Electronチュートリアル】マークダウンでスライドショーができるアプリを作ろう【第１回】](https://qiita.com/yasumichi/items/fc594e9ef1d7096bd56a)を2019年9月現在の最新版である Electron 6.0.10 向けに書き直したものです。

---

:warning: 長めの文章です。:warning:

[Electron](http://electron.atom.io/) は、元々は [GitHub](https://github.com/)によるテキストエディタ [Atom](https://atom.io/) を開発するために使用されていたJavaScript、HTML および CSS を使用してクロスプラットフォーム向けにデスクトップアプリケーションを開発できるフレームワークです。

現在の所、Microsoft Windows 7以上、Appleの macOS や各種 Linux ディストリビューションに対応しています。

Electron を利用したメジャーなアプリケーションと例して、[Visual Studio Code](https://code.visualstudio.com/)、[Slack](https://slack.com/intl/ja-jp/)、[Discord](https://electronjs.org/apps/discord)などがあります。

他人に教えられるくらい自分自身の知識を整理するため、このチュートリアルを書きたいと思います。

> 「マークダウンでプレゼンテーションしたいなら、『[Electron で Markdownプレゼン作成ツールを作って公開するまで - Qiita](http://qiita.com/yhatt/items/0bf65699a538d5508c33)』で紹介されている『[Marp - Markdown Presentation Writer](https://yhatt.github.io/marp/)』を使えばいいじゃないか。』

というあなた。正解ですが、学習のためには時には車輪の再発明も必要なのです。

- [車輪の再発明の効用 - プログラマが知るべき97のこと](http://プログラマが知るべき97のこと.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E8%BB%8A%E8%BC%AA%E3%81%AE%E5%86%8D%E7%99%BA%E6%98%8E%E3%81%AE%E5%8A%B9%E7%94%A8)


:exclamation: 2019年現在、[Marp - Markdown Presentation Writer](https://yhatt.github.io/marp/) は単体のアプリケーションとしての開発を中止し、Visual Studio Code のプラグインとして開発されているようです。

## 筆者の環境

- Microsoft Windows Pro (64bit)
- Node.js v10.16.3 (投稿時点の LTS)

## 前提となる基礎知識

- HTML
- JavaScript
- マークダウン
- Git （必要に応じ）
- コマンドプロンプト(Windowsの場合)など使用する OS の CUI インターフェース

## 作成するアプリケーションのイメージ

今回、作成するアプリケーションは、大きく左右の２つのペインで構成されています。

- 左側のペインはマークダウン形式のテキストを編集するためのエディタ
- 右側のペインはスライドのプレビュー

エディタには、[Cloud9 IDE](https://c9.io/) の主要なエディタとして開発されている[Ace](https://ace.c9.io/#nav=about)を採用します。(Electron アプリケーションでは、[CodeMirror](https://codemirror.net/) もよく採用されているようです。興味のある方は、CodeMirror で実装してみてください。)

スライドショーのフレームワークとしては、[remark](http://remarkjs.com/) という JavaScript のライブラリを採用します。

また、デザインには [Photon](http://photonkit.com/) のスタイルシートを採用します。

(第１回では、エディタ部分にマークダウンをコピペして、実際にスライドに反映させる部分、全画面でスライドショーを実行する部分まで作成します。第２回以降を書くかは未定ですが… :sweat_smile: )

## まずは Node.js 環境を準備しよう

[Node.js](https://nodejs.org/en/)は、Webブラウザ[Chrome](https://www.google.co.jp/chrome/browser/desktop/)に搭載されている[V8](https://developers.google.com/v8/)と呼ばれるJavaScriptエンジンを元に作成されたJavaScriptの実行環境です。

ブラウザに依存しない範囲であれば、そのまま JavaScript を実行できますし、[PhantomJS](http://phantomjs.org/)  や [jsdom](https://github.com/jsdom/jsdom) などのヘッドレスブラウザーを使用すれば、ブラウザが必要な JavaScript もブラウザなしで実行できるようになります。

現在、[Node.js](https://nodejs.org/en/) のトップページでは、LTS(Long Time Support)の推奨版と最新の V8 の機能を取り込んだ Current 版の大きく２つのバージョンのダウンロードボタンが表示されていますが、筆者も LTS 版の使用を推奨します。(2019年9月現在のLTS版は、v10.16.3 です。)

[Node.js](https://nodejs.org/en/) から、ダウンロードして普通にインストールしても良いですし、複数バージョンの Node.js を管理できる [nodebrew](https://github.com/hokaccha/nodebrew)、[nodeenv](http://ekalinin.github.io/nodeenv/)、[nvm](https://github.com/creationix/nvm) などのツールを利用しても良いでしょう。

いずれにしてもこの記事では、Node.js のインストール方法などについては、割愛させていただきます。(Qiita にもこれらの記事がいくつかあるようです。)

## プロジェクトの開始

Node.js の準備が完了したら、いよいよプロジェクトを開始します。まずは、プロジェクトを管理するためのフォルダ(ディレクトリ)を作成します。ここでは、remark-editor という名前で作成します。(なんという安直 :sweat_smile: )

:notebook: [GitHub](https://github.com/) などのアカウントがあれば、そちらでリポジトリを作成してクローンしても良いでしょう。GitHub の場合、リポジトリ作成時に Node.js 向けの .gitignore ファイルや LICENSE ファイルなどを同時生成することが可能です。(こういったサービスを使わないにしろ、何かしらのバージョン管理ツールを使うことは良い考えです。)

フォルダが作成できたら、Node.js のプロジェクトとして認識させるため、package.json というファイルを作成します。雛型を置いているサイトから、雛型をコピーしてきても良いのですが、ここでは、Node.js のパッケージマネージャーである [npm]( https://www.npmjs.com/) というコマンドラインツールを使用して作成したいと思います。

```console
> cd path\to\remark-editor ← 実際のパスを入力。行頭の > は、コマンドの入力を受け付けるプロンプトで環境により異なる。
> npm init          ←　このコマンドを実行する最初にいくつかの説明が表示されます。
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.  ← Ctrl + C 同時押しでいつでも強制終了できますよ、と。
name: (remark-editor) 　　←　パッケージ名を入力します。そのままエンターを押すと()内のデフォルト値が設定されます。(大文字使用不可)
version: (1.0.0) 0.1.0   ←　パッケージのバージョンを入力します。
description: Markdown editor for remark.js (For tutorial articles) ← パッケージの説明
entry point: (index.js) main.js ← 最初に起動される JavaScript のファイル名
test command:     ← テスト用のコマンドを入力します。そのままエンターを押しても良い。
git repository:   ← 必要に応じ、Git の公開リポジトリの URL を記述
keywords: Markdown, Presentation ← キーワードをカンマ区切りで入力
author: Anatano Namae  ← 作成者の名前を入力
license: (ISC) MIT  ← ライセンスを入力します。
About to write to /path/to/remark-editor/package.json: ← 以下、作成される package.json の内容が表示されます。 

{
  "name": "remark-editor",
  "version": "0.1.0",
  "description": "Markdown editor for remark.js (For tutorial articles)",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "Markdown",
    "Presentation"
  ],
  "author": "Anatano Namae",
  "license": "MIT"
}


Is this ok? (yes)  ← 上記内容で問題なければ、Enter キーを押す。
```

:star:[筆者が最初に作成した package.json](https://github.com/yasumichi/remark-editor/blob/init-package/package.json)

## Electron の開発に必要なパッケージをインストールする

これから作成する JavaScript 等を Electron アプリケーションとして起動するための **electron** パッケージをインストールします。(実際には、プロジェクトフォルダの配下の **node_modules** というフォルダの中に配置されます。)

npm の `install` サブコマンドを使用します。

```console
> npm install --save-dev electron
```

`--save-dev` オプションを指定すると package.json の "devDependencies" (開発時に依存するパッケージリスト)に追記されます。

```json:package.json(抜粋)
  "devDependencies": {
    "electron": "^6.0.10"
  }
```

アプリケーションの配布を考えている場合は、[electron-packager](https://github.com/electron/electron-packager) や [electron-builder](https://github.com/electron-userland/electron-builder) などもインストールしておくと良いでしょう。

このチュートリアルでは、electron-packager をインストールします。

```console
> npm install --save-dev electron-packager
```

## Ace Code Editor のビルド版をサブディレクトリとして配置する

:warning: npm リポジトリにも有志によるパッケージが存在しますが、しばらくメンテナンスされていないようです。 :warning:

「作成するアプリケーションのイメージ」で紹介したエディタ部分を担う Ace Code Editor の[ビルド版](https://github.com/ajaxorg/ace-builds)をダウンロードまたは Git により配置します。

ダウンロードにより配置する場合は、[Releases · ajaxorg/ace-builds](https://github.com/ajaxorg/ace-builds/releases) から、任意のバージョンや形式でダウンロードし、展開して配置します。

Git により clone する場合は、以下のコマンドを実行します。（アプリケーションのディレクトリを Git 管理していない場合）

```console
> git clone https://github.com/ajaxorg/ace-builds.git
```

アプリケーションのディレクトリを Git 管理している場合は、サブモジュールとして追加すると良いでしょう。

```console
> git submodule add https://github.com/ajaxorg/ace-builds.git
```

## Photon をダウンロードして必要なフォルダ・ファイルをコピーする

:warning: npm リポジトリに同名のパッケージがありますが、別物ですのでインストールする必要はありません。 :warning:

[Photon](http://photonkit.com/) のサイトで [Download Photon](https://github.com/connors/photon/archive/v0.1.2-alpha.zip) というボタンからダウンロードして展開します。

remark-editorのフォルダに photon フォルダを作成し、

- photon-0.1.2-alpha\dist\css\photon.min.css ファイルを remark-editor\photon\css\photon.min.css へ
- photon-0.1.2-alpha\dist\fonts\ フォルダを remark-editor\photon\fonts\ へ
- photon-0.1.2-alpha\LICENSE を remark-editor\photon\LICENSE へ

それぞれコピーします。最終的に以下のファイルがプロジェクトフォルダ配下に存在するようになります。

```
remark-editor\photon\css\photon.min.css
remark-editor\photon\LICENSE
remark-editor\photon\fonts\photon-entypo.eot
remark-editor\photon\fonts\photon-entypo.svg
remark-editor\photon\fonts\photon-entypo.ttf
remark-editor\photon\fonts\photon-entypo.woff
```

:star:[remark-editor/photon](https://github.com/yasumichi/remark-editor/tree/master/photon)

:notebook: fonts 以下は今回の記事では使用されませんが、じ後、ボタン等のアイコンとして使用できるようにコピーしています。

## remark をダウンロードして必要なファイルをコピーする

:warning: npm リポジトリに同名のパッケージがありますが、別物ですのでインストールする必要はありません。 :warning:

remark の [releases](https://github.com/gnab/remark/releases) から、[v0.14.0 のソース](https://github.com/gnab/remark/archive/v0.14.0.zip)をダウンロードして展開します。

プロジェクトのフォルダに js フォルダを作成し、remark-0.14.0/out/remark.min.js をコピーします。

実行には必要ありませんが、権利関係を明確にしておくため、remark-0.14.0/LICENSE を remark-editor/LICENSE-remark として保存します。

:star:[remark-editor/js](https://github.com/yasumichi/remark-editor/tree/master/js)、[remark-editor/LICENSE-remark](https://github.com/yasumichi/remark-editor/blob/master/LICENSE-remark)

## メインウィンドウの画面構成を HTML で作成する

以下のようにメインウィンドウの画面構成を HTML で作成します。

```html:mainwindow.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="photon/css/photon.min.css">
  <title>Remark Editor</title>
</head>
<body>
  <div class="window">
    <div class="pane-group">
      <div id="editor" class="pane"></div>
      <webview id="webview" class="pane" src="slideview.html" preload="js/webview.js"></webview>
    </div>
  </div>
</body>
</html>
```

説明不要かもしれませんが、以下の部分で Photon のスタイルシートを読み込んでいます。

```html
  <link rel="stylesheet" href="photon/css/photon.min.css">
```

画面構成に関わる部分は、以下の部分です。

```html
  <div class="window">
    <div class="pane-group">
      <div id="editor" class="pane"></div>
      <webview id="webview" class="pane" src="slideview.html" preload="js/webview.js"></webview>
    </div>
  </div>
```

window クラス内に pane-group クラス要素があり、editor と webview という id がついた pane クラス２つをグループ化しています。

:notebook: どのような部品が使えるかは、[Photon · Components](http://photonkit.com/components/)(英語)を参照してください。

`<webview>` は、別プロセスで動作する埋め込み Web ブラウザです。今回は、remark のスライドを表示しようと目論んでいます。

`<webview>` に表示するファイル(これから作成)を `src="slideview.html"` で指定しており、表示の際に注入する JavaScript ファイル(これから作成)を `preload="js/webview.js"` で指定しています。

:notebook: 現段階で mainwindow.html をブラウザで表示することができますが、ペインを分ける中央の線が表示されるだけです。

---
:warning: 2019年9月現在、`<webview>` の使用は推奨されていません。代わりに `<iframe>` や `BrowserView` を使うように推奨されています。これは、`<webview>` のバグ修正が、Chromium 側での修正に依存しているため、Electron 側でコントロールできないのが理由のようです。 :warning:

### 参考

- [&lt;webview&gt; Tag | Electron](https://electronjs.org/docs/api/webview-tag)
- [Migration to BrowserWindow in Electron - Speaker Deck](https://speakerdeck.com/nekobato/migration-to-browserwindow-in-electron)

---

## スライドのプレビューを表示する HTML ファイルを作成する

remark のソースに含まれている [remark-0.14.0/boilerplate-local.html](https://github.com/gnab/remark/blob/v0.14.0/boilerplate-local.html) を参考に以下の slideview.html を作成します。

```html:slideview.html
<!DOCTYPE html>
<html>
  <head>
    <title>Slides</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  </head>
  <body>
    <textarea id="source"></textarea>
    <script src="js/remark.min.js" type="text/javascript">
    </script>
    <script type="text/javascript">
      var slideshow = remark.create();
    </script>
  </body>
</html>
```

この内、以下の部分は、スライドのソースをマークダウンで記述する部分です。

```html
    <textarea id="source"></textarea>
```

`id="source"` のように識別をつけているのがポイントです。

## 各プロセスを制御する JavaScript ファイルを作成する(基本部分)

Electron のアプリケーションは、大きくアプリケーション全体を制御するメインプロセスとアプリケーションの描画を制御するレンダラープロセスで構成されます。作成の仕方によっては、レンダラープロセスが複数になる場合もあります。

### メインプロセス

メインプロセスである main.js を記述します。([初版](https://qiita.com/yasumichi/items/fc594e9ef1d7096bd56a)の投稿時は、[Electron1.3.xの最小構成 - Qiita](http://qiita.com/tadashiy1012/items/777ce1fe11d3aa40d460) の index.js を参考にしました。)

```js:main.js
// app および BrowserWindow への参照を読み込む
const {app, BrowserWindow} = require('electron');
// Node.js の path モジュールへの参照を読み込む
const path = require('path');

// Window を管理する変数
let win;

// メインウィンドウを作成するための関数
function createWindow() {
    win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(app.getAppPath(), 'js', 'mainwindow.js'),
            webviewTag: true
        }
    });
    win.loadURL(`file://${__dirname}/mainwindow.html`);
    win.on('closed', () => { win = null; });
}

// アプリケーションが準備できたらメインウィンドウを作成する
app.on('ready', createWindow);

// macOS ではすべてのウィンドウが閉じた際にアプリケーションを終了させる
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit();
});
```

以下、要点を解説します。

まず、electron のライブラリから必要な参照を取得します。electron は複数の参照を返すため、`{}`で受け取っています。

```js
const {app, BrowserWindow} = require('electron');
```

また、OS 毎のパスに使用する区切り文字の違いを吸収するため、Node.js の path モジュールへの参照を読み込んでいます。（Microsoft Windows では \、その他は / を使うという違いがあるため。）

```javascript
const path = require('path');
```

次のコードでWebブラウザのウィンドウを幅 800 ピクセル、高さ 600 ピクセルで作成します。また、メインウィンドウ内のレンダリングを担当するスクリプトを preload で指定し、`<webview>` タグを利用できるように指定しています。

```js
    win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(app.getAppPath(), 'js', 'mainwindow.js'),
            webviewTag: true
        }
    });
```

BrowserWindow へ渡せる他のオプションは、[new BrowserWindow([options])](http://electron.atom.io/docs/api/browser-window/#new-browserwindowoptions)(英語)を参照してください。

次のコードでWebブラウザに先ほど作成した mainwindow.html を [win.loadURL(url[, options])](http://electron.atom.io/docs/api/browser-window/#winloadurlurl-options) で読み込ませます。

```js
    win.loadURL(`file://${__dirname}/mainwindow.html`);
```

`file://` はローカルファイルを読み込むためのスキームを指定しています。

`${__dirname}` はスクリプトが存在するフォルダへのパスを返します。 

次のコードは、ブラウザが閉じられた時のイベントハンドラを記述しています。

```js
    win.on('closed', () => { win = null; });
```

`() =>` という記述は無名関数の宣言であり、`function ()` と同義です。

次のコードは、macOS 以外でウィンドウがすべて閉じられた時にアプリケーションを終了させることを意味しています。

```js
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit();
});
```

[process.platform](https://nodejs.org/dist/latest-v4.x/docs/api/process.html#process_process_platform) には、アプリケーションが実行されているプラットフォームを返します。`darwin` は macOS です。Microsoft Windows の場合は `win32` を Linux の場合は、`linux` を返します。

なお、macOS だけ扱いが異なる理由は、以下の記事を参照してください。

- [OS X用Electronアプリで，closeボタン処理と終了処理を区別する - Qiita](http://qiita.com/yukiB/items/0e2192c26c80bcbdbb90)(Electron v0.31.0 向け)
- [OS X用Electronアプリで，closeボタン処理と終了処理を区別する（Electron v1.1） - Qiita](http://qiita.com/yukiB/items/787a567777c0542f0e74)

#### 起動確認

Linux や macOSの場合、次のコマンドでアプリケーションを起動できます。

```console
$ ./node_modules/.bin/electron .
```

Windows の場合は、次のコマンドで起動します。

```console
$ .\node_modules\.bin\electron.cmd .
```

![mainwindow.png](https://qiita-image-store.s3.amazonaws.com/0/36738/4d1598e4-069c-fcf9-574d-faccc0185bf8.png)


メニューが表示されていますが、これは electron-prebuilt パッケージが開発用に付与しているメニューです。OSによっては、アプリケーション配布時には表示されません。(メニューの作成方法は、今回は触れません。)

毎回、上記のようなコマンドを入力するのも面倒なので `npm start` で起動できるように package.json を修正します。(行頭の + は書かない。)

```diff:package.json(抜粋)
   "scripts": {
+    "start": "electron .",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
```

これで次のコマンドでアプリケーションを起動できるようになります。

```console
$ npm start

> remark-editor@0.1.0 start /path/to/remark-editor
> electron .

```

### レンダラープロセス(メインウィンドウの表示等を制御)

左側のペインにエディタを表示するための js/mainwindow.js を作成します。

```js:js/mainwindow.js
document.addEventListener('DOMContentLoaded', () => {
  require('../ace-builds/src-min-noconflict/ace.js');
  ace.config.set('basePath', 'ace-builds/src-min-noconflict');
  ace.require('mode-markdown');

  // エディターの初期化
  var editor = ace.edit("editor");
  editor.getSession().setMode("ace/mode/markdown");
  editor.getSession().setUseWrapMode(true);
  editor.focus();
});
```

まず、DOM の読み込みが終わるのを待つために document オブジェクトの 'DOMContentLoaded' イベントを待つイベントリスナーを追加しています。

```javascript
document.addEventListener('DOMContentLoaded', () => {
  // この中に DOM 読込後の処理を書いていく
});
```

次のコードで Ace Code Editor の必要なライブラリを読み込ませています。

```js
  require('../ace-builds/src-min-noconflict/ace.js');
  ace.config.set('basePath', 'ace-builds/src-min-noconflict');
  ace.require('mode-markdown');
``` 

次のコードでエディタを実際に生成します。

```js
var editor = ace.edit("editor");
```

次のコードでシンタックスハイライトや入力補完が、マークダウン用になるようにモードを設定しています。

```js
editor.getSession().setMode("ace/mode/markdown");
```

次のコードで行が長くなった場合に自動で折り返して表示されるようになります。

```js
editor.getSession().setUseWrapMode(true);
```

最後にエディタにフォーカスを与えます。

```js
editor.focus();
```

#### 起動確認

ここで実際にアプリケーションを起動してみます。

```console
$ npm start
```

左側のペインに実際にエディタが生成されたことを確認してみましょう。実際に次の文を入力してみます。

```markdown
# マークダウンでスライドショー

- はじめに
-
```

問題がなければ、`- はじめに` を入力して改行した際に行頭の `- ` が自動入力され、次のように表示されるはずです。

![editor-highlight.png](https://qiita-image-store.s3.amazonaws.com/0/36738/1383af89-958a-abec-ac28-b04d8666024e.png)

うまく行かない人は、アプリケーションのメニューから View :arrow_right: Toggle Developer Tools の順に選択し、Console の内容を確認してみてください。

例えば、２行目の `require` で指定するパスが誤っている場合は、以下のようなエラーが表示されます。

![invalid_path.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36738/807d4ae9-7faa-a163-1d9b-aa28679d8bd1.png)


### レンダラープロセス(`<webview>` の表示等を制御)

webview に注入される js/webview.js を記述します。とりあえず、preload が成功しているかどうかを確認するために console にログを出力させます。

```js:js/webview.js
// preload されていることを console にログ出力する
console.log("js/webview.js was loaded");
```

このログは、メインウィンドウ側の開発者ツールには表示されないため、ゲスト側の開発者ツールを表示できるように js/mainwindow.js に以下のコードを追加します。

```js:js/mainwindow.js(追加)
// DEBUG_GUEST=true の時にwebview 側の開発者ツールを開く
var webview = document.getElementById('webview');
if (process.env.DEBUG_GUEST) {
  webview.addEventListener('dom-ready', () => {
    webview.openDevTools()
  });
}
```

これは、環境変数 `DEBUG_GUEST` の値が `true` の場合にゲスト側の開発者ツールを表示します。bash を使用している場合は、以下のように起動するとゲスト側の開発者ツールを表示できます。

```console
$ DEBUG_GUEST=true npm start
```

Microsoft Windows では、次のように起動します。

```
> SET DEBUG_GUEST=true
> npm start
```

問題がなければ、以下のようにログが出力されているはずです。

![DEBUG_GUEST.png](https://qiita-image-store.s3.amazonaws.com/0/36738/bf62f512-c1bb-f22a-524b-f9a2288ed3d2.png)

## エディタの入力内容をスライドに反映させる

`editor` の `change` イベントを補足し、改行などが行われたら、ゲスト側にメッセージと文書の内容を送信します。

```js:js/mainwindow.js(追加)
// 文書の変更を受け取るイベントハンドラ
editor.on("change", (e) => {
  if (e.start.row != e.end.row) {
    // 変更前と変更後で行が変わっていたら webview にメッセージと文書の内容を送る
    webview.send('update-markdown', editor.getValue());
  }
});
```

ゲスト側でこのメッセージを受け取れるように以下の内容を記述します。

```js:js/webview.js
const {ipcRenderer} = require('electron');

ipcRenderer.on('update-markdown', (event,markdown) => {
  let source = document.getElementById('source');
  source.innerHTML = markdown;
  slideshow.loadFromString(source.innerHTML);
});
```
実際に起動してエディタに以下の内容を入力してみてください。

```markdown
class: center, middle

# マークダウンスライドショー

???

タイトルページなり

---

# 目次

1. Electron とは
1. Node.js 環境の準備
1. プロジェクトの開始
1. ...

???

`???`でノートを記述できます。
```

![slidesview.png](https://qiita-image-store.s3.amazonaws.com/0/36738/d417e31c-c99d-326b-ec47-f6cd14154386.png)

## ゲスト側の全画面表示を捕捉してエディタ部分の表示を切り替える

ゲスト側にフォーカスがある時に `f` を押すと全画面表示に切り替わります。

![guest_fullscreen.png](https://qiita-image-store.s3.amazonaws.com/0/36738/229d7f59-133a-4142-fafc-bfeb0a99cb9f.png)

ですが、エディタ部分が表示されたままなのでどうせならエディタの表示・非表示を切り替えるようにしたいと思います。

```js:js/mainwindow.html(追加)
// 全画面表示時の制御
var editorPane = document.getElementById('editor');

webview.addEventListener('enter-html-full-screen', () => {
  editorPane.setAttribute('style', 'display:none');
});

webview.addEventListener('leave-html-full-screen', () => {
  editorPane.removeAttribute('style');
});
```

実際に起動して、ゲスト側にフォーカスを与え、`f` キーを押してみましょう。なお、`h` キーを押すと簡単なヘルプが表示できます。

![slideshow.png](https://qiita-image-store.s3.amazonaws.com/0/36738/b94b03eb-e37f-6637-5535-fb0dc33d0e92.png)

## パッケージ化

以下のようなコマンドで Linux 64bit 向けのパッケージが、
releases/remark-editor-linux-x64 に展開されます。(アーカイブはされないので別途、`zip` コマンドなどで１つのファイルにまとめる必要があります。)

```console
$ ./node_modules/.bin/electron-packager --platform=linux --arch=x64 --prune --out=releases .
```

Windows で実行する場合は、次のようなコマンドになるでしょう。

```
$ .\node_modules\.bin\electron-packager.cmd --platform=linux --arch=x64 --prune --out=releases .
```

次のように package.json にスクリプトを追加しても良いでしょう。

```diff:package.json(抜粋)
   "scripts": {
+    "package-darwin": "electron-packager --platform=darwin --arch=all --prune --asar --out=releases .",
+    "package-win32": "electron-packager --platform=win32 --arch=all --prune --asar --out=releases .",
+    "package-linux": "electron-packager --platform=linux --arch=all --prune --asar --out=releases .",
     "start": "electron .",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
```

このようにすると以下のコマンドで Microsoft Windows 用のパッケージを作成できます。

```console
$ npm run-script package-win32
```

## 終わりに

参考になりましたでしょうか？

私自身もまだまだ学習中の身なので至らないところがあったと思います。ご意見、お待ちしております。

需要があるようであれば、第２回でメニューの追加、ファイルの入出力について記述したいと思います。

なお、今回作成したソースは、[yasumichi/remark-editor](https://github.com/yasumichi/remark-editor/tree/electron_6_0)(electron_6_0 ブランチ) として GitHub で公開しています。

## 参考リンク

- [Electron Documentation](http://electron.atom.io/docs/)(英語)
- [markdown + remark.js + gh-pages でプレゼン資料を公開する - Qiita](http://qiita.com/harasou/items/1fa3cca6ac1ef175c876)
- [Node.js パッケージを作成する場合の .gitignore の例](https://github.com/github/gitignore/blob/master/Node.gitignore)