MarkdownをHTMLに変換するローカルサーバを作ってみた

## 目的
「Node.js超入門」という本でNode.jsを学習中なので例題として、
　MarkdownをHTMLに変換するローカルサーバ
を作った。
Node.jsにはmicromarkというモジュールがあって、簡単に変換できるようだ。

## 環境
``` bash
npm install -g express-generator
```
wslでnpmをインストールする。Microsoftの[手順](https://learn.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-wsl)通り  
そのあとexpress-generatorをインストールする

## ライブラリのインストール
``` bash
express -e markdown_conv
cd markdown_conv
npm install --save express-fileupload
npm install --save markdown
npm audit fix --force
npm install
```
プロジェクト名を markdown_conv にした  
本の通りにejsオプションをつけている。
- ファイルアプロードのモジュール`express-fileupload`
- マークダウンのライブラリ`micromark`
- マークダウンのルール`micromark-extension-gfm`
をインストールしている。脆弱性対応してインストールする

## ソース変更
### /app.js
``` javascript:app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const fileUpload = require('express-fileupload');  // 追加

var indexRouter = require('./routes/index');
var usersUpload = require('./routes/upload'); // 変更

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(fileUpload());  // 追加

app.use('/', indexRouter);
app.use('/upload', usersUpload);  // 変更

// 以下略

```
自動でできたファイルから変更する
- express-fileuploadを有効にする 
`const fileUpload = require('express-fileupload');`　と  
`app.use(fileUpload());` を追加  
- サンプルのusersはいらないので削除して、uploadを追加する
`var usersRouter = require('./routes/users');` を
`var usersUpload = require('./routes/upload');` に変更
`app.use('/users', usersRouter);` を
`app.use('/upload', usersUpload);` に変更

### view/index.ejs
``` html:index.ejs
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="content-type"
            content="text/html"; charset="UTF-8">
        <title><%=title %></title>
        <link type="text/ccs" href="./style.css" rel="stylesheet">
    </head>
    <body>
        <head>
            <h1><%=title %></h1>
        </head>
        <h1>ファイルアップロード</h1>
        <form action="/upload" method="POST" enctype="multipart/form-data">
          <input type="file" name="file">
            <button type="submit">送信</button>
        </form>
    </body>
</html>
```
`form`を追加してファイルを送信できるようにする。`enctype="multipart/form-data"`がないとファイルアップロードできないようなので注意  
これで/uploadに対してファイルがpostされるようになる

### routes/upload.js
``` javascript:upload.js
var express = require('express');
var router = express.Router();
var micromark = require('micromark').micromark
var gfm = require('micromark-extension-gfm').gfm
var gfmHtml = require('micromark-extension-gfm').gfmHtml

// POSTを受ける
router.post('/', function(req, res, next) {
  fileContent = req.files.file.data.toString('utf8'); // ファイルの内容
  res.render('upload', { content: micromark(fileContent,{
    extensions: [gfm()],
    htmlExtensions: [gfmHtml()]
  }) });
});

module.exports = router;
```
`micromark`, `gfm`, `gfmHtml`がmicromarkのライブラリ  
`express-fileupload`を有効にしておくと、アップロードファイルの内容が  `req.files.file.data.toString('utf8');`  
で取得できる
それを`micromark`でhtmlに変換する。
`gfm`というのはGitHub Flavored Markdownのことで、githubで使っているマークダウンのフォーマットのようだ。  
### upload.ejs
``` html:upload.ejs
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="content-type" content="text/html" charset="UTF-8">
    </head>
    <body>
        <%-content %>
    </body>
</html>
```
変換ライブラリはhtmlを返すので、htmlのbodyにそのまま入れる。`%-`とすることでHTMLエスケープしないでそのまま入れる。

## 使い方
``` bash
npm start
```
これで`localhost:3000`にhttpサーバが立つのでchromeでアクセスする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99409/07535795-5d9f-4a78-bb33-1d8bbc152697.png)

マークダウンファイルを選択を押して、ファイルを選んだあと、送信ボタンを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99409/bac50b18-243a-4168-b5dc-786516c3cc4a.png)

変換されてこういう感じで表示される。


## こんなサーバ作って変換するよりgithubにpushすれば表示されるよね。
実際に作ってみて勉強になった