✍️

初めての技術書執筆で学んだ実践ノウハウ

に公開

はじめに

この度、技術評論社様より『先輩データサイエンティストからの指南書』という本を出版しました。データサイエンティストが実務で躓きがちなエンジニアリングスキルについて、実践的な知見をまとめた一冊です。

執筆メンバーは計5名であり、いずれも執筆は初めてでしたが、執筆を進める中で多くの学びがありました。本記事では、執筆の過程で得られた技術書執筆に関する知見について整理して共有します。書籍の具体的な内容には触れないため、ご興味を持たれた方は同じ執筆メンバーの@nash_efpnoteをご参照ください。

本記事が書籍執筆の進め方の一例として、これから執筆をされる方の参考になれば幸いです。

執筆プロセスの全体像

まず、前提として執筆の流れを簡単に説明します。概ね次のようなフローで進みます。

  1. 企画書作成
    執筆する書籍のコンセプトを固めるフェーズです。書籍のコンセプトやターゲット層、具体的な章の構成などを企画書として整理し、出版社に提出します。

  2. 原稿執筆
    企画が無事通れば、執筆作業開始です。随時、出版社の担当者の方にもフィードバックを頂きつつ、原稿を書き上げます。

  3. 組版・校閲
    完成原稿を実際の書籍のレイアウトに落とし込みます(この作業を組版と言います)。組版後は執筆者と出版社の間で複数回の修正を往復し、最終的に内容がfixされます。

  4. 出版
    確定した原稿が印刷所へ入稿され、製本されます。そして、全国の書店に配本され晴れて刊行となります。

執筆内容のボリュームや作業にかけられるリソースにもよりますが、今回執筆した書籍の場合は以下のようなタイムスケジュールで進みました。

  1. 企画書作成(2~3か月)
  2. 原稿執筆(約10か月)
  3. 組版・校閲(約2か月)

GitHubによる原稿管理

ここから、執筆に関する具体的なノウハウについて紹介します。

私たちのケースでは共同で執筆作業を進めるにあたり、GitHubでMarkdown形式での原稿管理を採用しました。共同執筆においてGitHub上で作業を行うことには次のようなメリットがありました。

  1. 安全にバージョン管理ができる
  2. Pull Requestを通してレビューフローが回せる
  3. 原稿とサンプルコードを併せて管理できる

以下ではそれぞれについて説明します。

  1. 安全なバージョン管理
    執筆の過程では表現を書いたり消したりしながら納得のいくまで推敲を繰り返します。Gitでバージョン管理しておくと、仮に「前の表現の方が良かった」となった際にも簡単に復元可能なため、安心して試行錯誤することができます。
    また、執筆途中に出版担当者の方にレビューを依頼する際にも、その時点の原稿をGit Tagでスナップショットとして記録しておくことができます。

  2. Pull Requestによるレビュー運用
    各章ごとに執筆担当者とレビュー担当者をアサインし、PRを通してレビューを行いました。これにより、執筆作業が各担当者内のみで閉じることなく互いに知見を共有しつつインタラクティブに行え、共同執筆の利点を活かすことができたように思います。
    また、PRのテンプレート機能やGitHub ActionsによるCIなどのGitHubの機能を利用することで、執筆者間で執筆内容を標準化することにも一定の効果がありました。このあたりのレビュープロセスの詳細については後述します。

  3. 原稿とサンプルコードの一元管理
    本書ではGitHubでサンプルリポジトリを公開しており、コード例を通してハンズオン形式でも学べるスタイルを取っています。GitHubを使うと原稿とコードを同一のリポジトリで管理できるため、本文と参照コードの内容の乖離を防ぎつつ執筆作業を進めることができました。

一方で、これらの利点の多くは作業コストとのトレードオフでもあります。振り返りを通して「毎回コミット → push → PR → レビューというフローはやや冗長だったかもしれない」という意見もありました。例えば、Notionのコメント機能やサジェストモードを使うのも一つの有効な代替案だったかと思います。

とはいえ、上記のようなGitHubならではのメリットも確かにあり、特に今回のような5名規模の執筆では恩恵が大きかったと感じます。複数人で執筆する際は、選択肢の一つとして検討の価値があると思います。

レビュープロセス

執筆時のレビュープロセスについてもう少し深ぼります。

同期と非同期の使い分け

前述の通り、章単位で執筆担当・レビュー担当を割り当て、次の二段構えでレビューを行いました。

  1. 各章ごとでの担当者間の非同期的なレビュー
  2. メンバー全員で集まって章全体を通した同期的なレビュー(内輪では「ワイワイレビュー」と呼んでいました)

まず1の非同期レビューで十分に磨き込んだ後、2で全員の目を通して気になるところを指摘しあう、というサイクルを複数回重ねることで、段階的に内容をブラッシュアップしていきました。この運用により、作業の切り分けと各執筆者の持つ知見のマージを両立し、効率的に執筆作業を進められたように思います。

なお、章全体のレビューを行う際には、次の手順で該当箇所に関するPRを作成しました。

  1. レビューする章を一度まるごと削除
  2. その削除コミットをrevert
  3. レビュー用のPRを作成

紙面でのレビューの重要性

レビューコメントの記録自体はPR上で行いますが、紙に印刷した状態でのレビューの効果も見落とせませんでした。上手くは説明できませんが、スクリーン上では見逃してしまう表現の違和感や論理構造のおかしな点に紙面上では気づく、といったことが多々ありました(スクリーン上だと気づかない内に目が滑っているのだと思います)。

毎回のレビュー時に印刷するのは大変ですが、原稿作成の段階で少なくとも一度は紙面に印刷してレビューすることを強くおすすめします。なお、紙面でのレビュー時にはVS Codeの拡張機能(Markdown PDF)でPDFに変換したものを印刷していました。

執筆スタイルの統一と品質管理

共同執筆を行う上で、スタイルの標準化は一つの課題となりました。多少の文体の違いは執筆者ごとの個性として歓迎されるものですが、表記ゆれやスタイルのばらつきは全体での一貫性を損なうため避けたいものです。

そこで、以下のような工夫を行いました。

執筆ガイドラインの作成

執筆の前提となるガイドラインを用意しました。以下が用意したガイドラインの一部です。

### 文体

- ですます調に統一する。
- 一人称は「筆者」で統一する。

### 構成
- 階層は以下の構成を基本とする。

```
# 第3章 コードの品質管理

## 3.3 品質の高いコードとその実現方法

### 3.3.1 関数

-- 以上はマスト、以下は必要に応じて --

#### 3.3.1.1 関数の役割

##### 再利用性
```

- 各章の最後にはまとめを書く。

- 必要に応じて適宜脚注を入れる。

```
テキスト[^footnote]
[^footnote]: 注釈内容
```

- コラムはNOTEとしてハイライトする。

```
> [!NOTE]
> Python Scriptのデバッグ  # ここにコラムのタイトル
> 配布しているリポジトリでは、以下の3つの単位でデバッグを実行できるように設定しています。
> ...
```

...

上記以外にも、図表のタイトルやナンバリングの規則、コードブロックの取り扱い、括弧の使い方(全角 or 半角)などをルールとして設けつつ、執筆の過程で気づいた項目を随時追加し段階的に整備していきました。

これらのガイドラインはPRテンプレートに記載し、マージ前にチェックできるようにしました。

textlintによる表記ゆれの自動チェック

複数人、あるいは一人でも執筆の過程で避けられないのが表記ゆれです。たとえば Numpy / numpy / NumPy のどれに統一するか、など表記が揺れうる箇所は無数に存在します。

表記ゆれに対しては、文章校正を行うためのリンターであるtextlintによるチェックをGitHub ActionsのCIに組み込み、機械的に検出できる仕組みを導入しました。

なお、表記ゆれは最初にすべて洗い出すことは不可能なため、気づいたものを随時辞書に追加して逐次的に改善していきました。当然100%の担保はできませんが、大幅な改善につながりました。

参考までに、以下が実際に用いた設定ファイルの例です。

prh.yml - 表記ゆれ辞書

version: 1

rules:
  - expected: NumPy
    patterns:
      - numpy
      - Numpy

  - expected: scikit-learn
    patterns:
      - sklearn
      - Sklearn
      - scikitlearn
      - scikit learn

.textlintrc - 設定ファイル

{
  "plugins": {},
  "filters": {
    "comments": true
  },
  "rules": {
    "prh": {
      "rulePaths": [
        "./prh.yml"
      ]
    }
  }
}

package.json - スクリプト設定

{
  "name": "ds_instructions_guide",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "lint": "textlint 'book/**/*.md'", 
    "fix": "textlint --fix 'book/**/*.md'"
  },
  "devDependencies": {
    "textlint": "^14.4.2",
    "textlint-filter-rule-comments": "^1.2.2",
    "textlint-rule-prh": "^6.0.0"
  }
}

GitHub Actions - CI設定

name: spelling inconsistencies

on:
  pull_request:

defaults:
  run:
    working-directory: book

jobs:
  ci:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.12"]
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: install
        run: npm install
      
      - name: lint
        run: npm run lint

その他のTips

最後に、その他のこまごまとしたTipsについてご紹介します。

誤字脱字のチェック

どうしても見落としが発生してしまう誤字脱字に対しては、生成AIによるチェックも一定の効果がありました。当然100%ではありませんが、人間の目では気づかないような微妙な誤りを指摘してくれることもちらほらあり、品質向上に役立ちました。

作業画面のキャプチャ

画面のキャプチャを本文中に挿入したい場合、macOSでは「Command + Shift + 4 + Space」でウィンドウごとまるっとスクリーンショットを撮ることができます。ただし、デフォルトではウィンドウの周りに影がついてしまうため、後続のトリミングや画像の加工に支障をきたします。optionキーを駆使することで、影を含めないままスクリーンショットを撮ることができます(参考:Macでスクリーンショットを撮る)。

組版後のレビュー

組版後はファイル形式がMarkdownからPDFとなるため、GitHubから離れてGoogle Driveのコメント機能を通したやり取りに移行しました。Google Driveでは複数人が同時にコメントを付けることができるため、共同での内容のレビューに役立ちました。ただし、Acrobat Readerでは見える注釈がGoogle Driveでは正しく表示されない、といった問題もあり注意が必要でした。

モチベーションの維持

執筆作業は長期戦になるため、モチベーションを保つための工夫も重要でした。個人作業に終始すると、どうしてもモチベーションの維持が難しくなります。そこで、適宜もくもく会を開いたり執筆合宿を開催したりして、同期的に作業する機会を設けました。これによって、チームとして一定の熱量を保ちつつ最後まで作業を継続できたように思います。

おわりに

技術書執筆におけるGitHubによる原稿管理、それに付随するレビュー運用や品質標準化の工夫について紹介しました。執筆作業は多くの時間と労力を要しますが、書き上げたものが出版されて読者の手に渡るのは何にも代えがたい喜びがありました。本記事が、これから執筆をされる方の一助になれば幸いです。

最後に、技術評論社のご担当者様には大変お世話になりました。この場をお借りして改めてお礼申し上げます。

Discussion