2020年初めて技術書をAmazonKDP(kindle)に出版したので必要な技術を軽くまとめる

# AmazonKDPに出版ときに必要な技術を書く・まとめる

## とりあえずわかる人はこれだけみたらわかるものを置いておく

最初 `GitBook` で作ってたので `node.js` ベースになってるけど、途中から `pandoc` という `brew install pandoc` でインストールできるもので、作り始めたので `package.json` とか作らなくても `makefile` を作ってで `make up` すると自動でビルドしてくれる感じにしてもいいと思う。

動いたらいいので結構雑にスクリプト書いてます。

```package.json
{
  "scripts": {
    "build": "touch publish/merged.md && rm publish/merged.md && node publish/build.js",
    "epub": "npm run build && pandoc publish/merged.md -f markdown -t epub --self-contained -s  -o publish.epub -c assets/github.css --toc --toc-depth=2 --epub-cover-image=images/cover.png && open publish.epub",
    "epub-free": "touch pub-1-free/merged.md && rm pub-1-free/merged.md && node pub-1-free/build.js && pandoc pub-1-free/merged.md -f markdown -t epub --self-contained -s  -o pub-1-free.epub -c assets/github.css --toc --toc-depth=2 --epub-cover-image=images/cover-free.png && open pub-1-free.epub",
    "ls-highlight": "pandoc --list-highlight-languages",
    "open": "open publish.epub",
    "download": "npm run build && node publish/download.js && node publish/replace.js"
  },
  "devDependencies": {
    "request": "^2.88.0"
  }
}
```

markdownファイルをまとめてくれるやつ。 `.md` ファイルはただのテキストファイルなので、ファイルの内容を足していけば、ファイルを分けて管理できます。

```build.js
#!/usr/bin/env node

const fs = require('fs')

const path = './publish'
let mergedMdContent = ''

try {
  fs.readdirSync(path).forEach(fileName => {
    if (fileName.includes('.DS_Store')) return
    if (!fileName.includes('.md')) return
    mergedMdContent += fs.readFileSync(`${path}/${fileName}`, 'utf-8') + '\n'
  })

  // pandocを実行するフォルダの階層にあわせる
  mergedMdContent = mergedMdContent.replace(/\.\.\/images/g, './images')

  fs.writeFileSync('./publish/merged.md', mergedMdContent)
  console.log(`merged!`)
} catch (err) {
  console.log(`Oh no, An error occurred! ${err.message}`)
  process.exit(-1)
}
```

最初、gyazoさんに画像をホストしていたので、途中でダウンロードした。スクショしたらすぐにマークダウンの画像リンクが作れるので、めっちゃ便利だった。画像のダウンロードを非同期処理なJavaScriptで書くのとても面倒なのですね… :sad:

```download.js
#!/usr/bin/env node

console.log('Start: ')

const fs = require('fs')
const request = require('request')

const merged = fs.readFileSync('publish/merged.md', 'utf-8')
const re = /(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+.png)/gi
let urls = merged.match(re)
if (!urls) return
console.log(urls)

function requestSiteData(urls) {
  if (urls.length) {
    const url = urls.shift()
    const name = url.replace('https://i.gyazo.com/', '')
    const imagePath = `images/${name}`

    try {
      fs.statSync(imagePath)
      console.log(`Exists: ${imagePath}`)
      return requestSiteData(urls)
    } catch (e) {}
    console.log(`Download: ${imagePath}`)

    request({ method: 'GET', url: url, encoding: null }, function(
      error,
      response,
      body
    ) {
      if (!error) {
        fs.writeFileSync(imagePath, body, 'binary')
      }

      requestSiteData(urls)
    })
  } else {
    // 再帰の終了
    console.log('fin')
  }
}

requestSiteData(urls) //start requesting data
```

gyazoさんへのリンクをダウンロードしたフォルダに書き換えたやつ。

```replace.js
#!/usr/bin/env node

const fs = require('fs')

try {
  fs.readdirSync('publish').forEach(fileName => {
    if (!fileName.includes('.md')) return
    console.log(fileName)
    let content = fs.readFileSync(`publish/${fileName}`, 'utf-8')
    content = content.replace(
      /https:\/\/i.gyazo.com\//g,
      '/Users/yk/workspace/books/lets-sql/images/'
    )
    fs.writeFileSync(`publish/${fileName}`, content)
  })

  console.log(`fin!`)
} catch (err) {
  console.log(`!Error! ${err.message}`)
  process.exit(-1)
}

```

こんな感じのdir構成

```
$ tree -L 2 publish                                                                                                  (git)-[master]
publish
├── 4.md
├── 5.md
├── 6.md
├── 7.md
├── 8.md
├── build.js
├── download.js
└── replace.js
```


## Q&A

### Q 出版する時の形式は？

`KDP ファイル形式` とかでググるとでてくる。


- HTML 
- Word 
- MOBI
- ePub
- PDF 
- リッチテキスト 
- プレーンテキスト 

今回私が試したのは

- PDF （固定長で作りたい）
- ePub（ユーザーの設定で文字のサイズを調整できる）

の二つです。

### Q. markdownをまとめてくれる何かはどうすればいいの？

以下のようなツールが便利でやり方の記事とかがたくさん出てくる。

1. [GitBook](https://github.com/GitbookIO/gitbook)
1. [pandoc](https://pandoc.org/)
1. [でんでんコンバーターさん](https://conv.denshochan.com/)

GitBookは少し古いバージョンがOSSとしてGitHubにホストされているので無料で使えて、PDFにもepubにも変換できた。ちょっと古いのでいろいろと困ってpandocに乗り換えたけど、普通に使いやすい。GitBookはOSS版じゃないWeb版に注力しているみたい by [vuepress の why not?](https://vuepress.vuejs.org/guide/#why-not)

Vue.js使える人は、PDFとかepubとかじゃなくてドキュメント形式の管理したいならVuePressとかでいいと思う。

pandocは `brew install` で使えるのでMacユーザーは一番使いやすいのではなかろうか。pdfもepub形式も使えるっぽいので便利。

でんでんコンバーターさんもWebで使えるのでさくっと試したいときは便利。

### Q. KDPは無料で公開できるの？

ここ盲点だったのですが、技術書などの電子書籍は無料公開は基本的に駄目っぽいです。
90日に5日だけ無料公開できます。

### Q. 印税はいくら？

- 35%
- 70%

の二種類が選べるのだけど、それぞれできることと、制約があったりするのでちゃんと調べたほうがいい。

Amazon独占販売なら70%で売れるけど、同時にUnlimited（無限に読めるやつ）に登録されるっぽいから、1ページいくらと安い金額で読めてしまう的な議論がたくさんブログでささやかれています。どうぞ https://google.com ご検索を

### Q. 登録してから公開までに何時間くらいかかる？

```
Kindle ダイレクト・パブリッシングをご利用いただきありがとうございます。

お客様の本『XxxxxxxXXX』が Kindle ストアで購入可能になり XXXXXXXX
```

的なメールが6時間後くらいに来ていたので、適宜確認が行われて公開されている印象です。

### Q. 何を出版したの？売れた？

秘密です！まだ見てませんが、売れてないと思います！

.