エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

技術書典への参加から執筆の諸問題対応とテンプレート公開までの記録

f:id:vaaaaaanquish:20210720112534p:plain

 

こんにちは。エムスリーの河合(@vaaaaanquish)です。

現在開催中の技術書典11で、エムスリーテックブック#3 に「Rustによる機械学習概覧」という章を寄稿しました。

techbookfest.org

本記事は、そのテックブックを書くにあたっての社内ドキュメントを作ろうと思ったのですが内部に閉まっている意味はないと感じたので全て公開してしまおう、という趣旨の記事です。

 

参加登録から執筆開始まで

参加が初めての場合は、「技術書典 参加 報告」等でググると過去の様子が見られるので参考にすると良いです。 また、公式に出ている「利用サーベイ」はテーマや動向を探る上で参考にしやすいので、いくつか見てみるのをオススメします。

技術書典9 オンラインマーケット利用サーベイ - 技術書典ブログ

 

技術書典の参加公募は、大体1ヶ月半〜3ヶ月前から始まります。技術書典11の開催は 7月11日 からでしたが、技術書典11の参加登録への抽選申し込み期限は 5月23日 23:59 でした。 過去一度参加していれば、公募開始のメールが届きます。私はTwitterが好きなので、技術書典の公式Twitterアカウントのツイートで知りました。少しアンテナを貼っておく必要はあります。 エムスリーでは、社内にtechbookfestのツイートが流れるSlackチャンネルがあるのと、技術書典公式からのメールが流れるメーリングリストがあります。

技術書典 公式アカウント (@techbookfest) | Twitter

参加には審査があるのですが、審査に応募する時点である程度の「審査用のサークル説明文」と「代表者情報」が求められます。 今回は、この審査の前の時点で「VPoEである山崎さんに参加について相談」「社内説明会」を実施して、参加者と大まかなテーマを集め、議論の上で説明文を作成しました。

審査の詳細は不明なので何とも言えないですが、エムスリーは以下のような文章で申請しました。

エムスリー株式会社 エンジニアリンググループの有志による合同本 第3段です。
幅広いメンバーで、業務内外で得た知識をまとめる一冊を書き上げます。
Rust, Unity, Pythonといった言語で、 Machine Learning, ゲーム開発、Kubernetesなどのテーマをとりあげる予定です。


■サークルの活動がわかるURL等
- エムスリーテックブック#1:https://www.m3tech.blog/entry/m3techbook-01
- エムスリーテックブック#2:https://techbookfest.org/product/5768508210151424
- エンジニアリンググループメンバーが執筆するテックブログ:https://www.m3tech.blog/entry/2021/05/21/160000

エムスリーは過去に同様のフォーマットで抽選に参加して落ちた事があるので、他の参加者との相対的なものもあるかもしれません*1

 

メンバー集めと参加形態

同人誌とは言え、技術書を書くというのは大変です。個人が書く文字数を事前に調査した所、エムスリーフォーマットで1人20ページ書く前提で進めた場合、一般的な技術ブログ5記事分は必要になることが分かっていました。

  • 2021年のm3 techblogの文字数平均:5325.2
  • エムスリーテックブック2の文字数平均:25870.0

このような情報を共有し、事前に説明会などで大変さを伝えておくことも大事です。 一方で、1個人として技術書を書ききる事や大きなイベントに参加すること、会社として技術アピールに繋がる事も考慮できます。 実際、AI・機械学習チームリーダーの大垣さん (@hi_king) は、エムスリーを最初に知ったのはエムスリーテックブック#2だったとの事で、大きく会社に貢献しているとも言えます。

こういった情報を共有しながら、一緒に書いてくれる人の負担を減らしつつ協力して書いていける体制づくりが必要です。 エンジニアだけでなく、技術系の役員や採用広報担当者の手も借りながら進めると良いでしょう。

 

今回は、トライアルでオフライン会場での開催がありましたが、エムスリーはオンライン参加のみでした。 そのため、販売については「PDF販売」もしくは「後から印刷」のみを想定すれば良く、ここまで書いてあるような事柄が決まれば、参加について概ねの事が考慮できる状態でした。

オフライン会場に参加する場合は、印刷所への入稿や金銭面の考慮、ポップや見本誌、あの布などの準備、会場での対応の設計が必要になるのでもう少し忙しく、締切がタイトになる事を留意した方が良さそうです。今回はオンライン参加のみなので、この辺りについては他のブログにお任せします。

 

エムスリーテックブックテンプレートRepository

執筆にあたっては、Re:VIEW、Sphinx、InDesign、LaTeX、Word、…といった選択肢がありますが、エムスリーではRe:VIEWを利用しています。

今回引き継ぎを受けた時点で、エムスリーテックブック#1で使われたRe:VIEW 3.2からの更新がなくbuildできない状態だったので、Re:VIEW 5.2にアップデートした後、フォーマットを揃えて以下のRepositoryに公開しました。

github.com

このRepositoryでは、いくつかの箇所を変更するだけでエムスリーテックブックと同等の環境で執筆が始められるだけでなく、CircleCIによってPull Request毎にPDFがbuildされ、SlackにそのPDFへのリンクが投稿されるようになっており、スムーズな相互レビューが可能です。

エムスリーフォーマットでは、設定や見た目に関していくつか独自の改修しています。

 

config.ymlの分割

Re:VIEWのデフォルトプロジェクトでは1つの config.yml が用意されていますが、実際のイベントではPDFデータと印刷用データを作成する必要があります。 Re:VIEWでは inherit というキーワードで設定ファイルの継承関係を指定できるため、これを使って共通設定ファイルとそれぞれの設定差分ファイルに分割しました。

下記の例では刊行日や著者名、奥付設定などの共通設定は config.yml で定義し、PDF版と紙版のそれぞれの差分を各ファイルで定義しています。

src/config-pdf.yml

inherit: ["config.yml"]
# 出力ファイル名
bookname: techbook-pdf
# media=ebook : pdf用設定
texdocumentclass:
  [
    "review-jsbook",
    "media=ebook, paper=b5, twoside, fontsize=10pt, head_space=28mm, number_of_lines=37, gutter=26mm, footskip=10mm, serial_pagination=true, cover=true",
  ]

src/config-paper.yml

inherit: ["config.yml"]
# 出力ファイル名
bookname: techbook-paper
# media=print : 印刷用にトンボを表示
# cover=false : 表紙は印刷所側のテンプレを利用するため非表示
# hiddenfolio=nikko-pc : 印刷所ごとに隠しノンブルの設定を変更(nikko-pc = 日光企画, marusho-ink = 丸正インキ, shippo = ねこのしっぽ)
# 詳細は以下を参照
# https://review-knowledge-ja.readthedocs.io/ja/latest/latex/review3-latex.html#296393b6ba6b0a3a20c6fe2f717e73f2
texdocumentclass:
  [
    "review-jsbook",
    "media=print, paper=b5, twoside, fontsize=10pt, head_space=28mm, number_of_lines=37, gutter=27mm, footskip=10mm, serial_pagination=true, hiddenfolio=nikko-pc, cover=false",
  ]

f:id:mikesorae:20210720043524p:plain:h350f:id:mikesorae:20210720043601p:plain:h350
PDF用出力(左)と印刷用出力(右)

Re:VIEW3からは textdocumentclass で簡単にPDFや印刷用の設定が切り替えられる他、カバー画像の有無やノンブルの連番設定などもここで設定できるようになりました。*2

 

PDF印刷設定関連パラメータの変更

PDF/印刷設定に関係のあるパラメータをいくつかご紹介します。

 

hiddenfolio=nikko-pc

隠しノンブルや塗り足し設定用のパラメータです。

印刷所によっては塗り足しの幅や空白ページへのノンブル(冊子内でのページの通し番号)指定を求められることがあるため、必要に応じてこのパラメータを指定します。

日光企画を利用する際は hiddenfolio=nikko-pc となります。*3

 

serial_pagination=true

Re:VIEWのjsbookのデフォルトの出力では、大扉と目次ページのページ番号が i 始まりのローマ数字になります。 上記の隠しノンブルが有効になっていれば怒られないかもしれませんが、アラビア数字でないと怒られるケースもあるため、serial_pagination=true でアラビア数字の通し番号に変更しています。

 

cover=false

表紙データは背表紙デザインを含んでいたり、塗り足しが必要なケースが多いため、印刷所ごとの入稿用テンプレートを使用します。

例: 日光企画のトンボテンプレートダウンロードページ http://www.nikko-pc.com/offset/template/tonbo.html

この場合入稿データに表紙画像は必要ないため、cover=false で表紙出力をオフにします。*4

 

gutter=26mm

gutter(ノド)は印刷物を綴じる際の余白の部分のことを指します。 印刷物ではノドをやや広めに取ったほうが開いたときに見やすくなりますが、PDF版(B5サイズ)では26mmにしておくとページを移動したときに左右のブレが無いため読みやすくなります。 (なおこちらは本記事執筆中に気づいたため、今までお買い上げいただいたPDF版では多少左右にブレがございます)

 

奥付出力内容のカスタマイズ

Re:VIEWの config.yml には著者やデザイナや監修者を指定する項目が用意されていますが、デフォルトで奥付に表示されるのは以下で指定されている項目のみです。

https://github.com/kmuto/review/blob/72480f5930f54241067ac9493c0d98fbadf891d8/lib/review/configure.rb#L66

# 著者, 監修者, 翻訳者, デザイナ, ......
'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt], 

config.yml に以下を追加することで、奥付に表示される項目の追加や表示順序を変更できます。

colophon_order:
  [
    "aut",
    "spn",
    "ths",
    "csl",
    "trl",
    "dsr",
    "ill",
    "cov",
    "edt",
    "pbl",
    "contact",
    "prt",
  ]

 

タイトルページのカスタマイズ

デフォルトのタイトルページでは、config.ymlbooktitleaut に指定した内容が自動的に出力されます。 弊社では複数名で執筆しているので aut が複数名になるのですが、タイトルページの名義は「エムスリーエンジニアリンググループ執筆部」としたかったため、独自texファイルを使ってタイトルページをカスタマイズしました。

独自texファイルの作成方法については下記サイトを参考にさせていただきました。

kyabe.net

以下はカスタマイズ前後の比較画像です。

f:id:mikesorae:20210720032659p:plainf:id:mikesorae:20210720032723p:plain
カスタマイズ前(左)とカスタマイズ後(右)

タイトルページで独自のtexファイルを使用するためには、config.yml で以下を指定します。

src/config.yml

...
titlefile: title.tex
...

title.texsty/review-base.sty から \begin{titlepage}\end{titlepage} の間をコピーし、文字サイズやマージンの調整を行いました。 著者名の部分は直接文字列に書き換えており、 {エムスリーエンジニアリンググループ執筆部} の部分に指定した文字列がそのまま表示されます。

src/title.tex

\begin{titlepage}
\thispagestyle{empty}
\begin{center}%
\mbox{} \vskip5zw
\reviewtitlefont%
\vskip 15em%
{\Huge\review@booktitlename\par}%
\ifdefined\review@subtitlename
\fi
\vskip 2em%
{\Large
\lineskip .75em
\begin{tabular}[t]{p{\textwidth}}%
\centering{エムスリーエンジニアリンググループ執筆部}
\end{tabular}\par}%
\vfill
{\large\review@date \review@intn@edition\hspace{1zw}\review@intn@publishedby\par}%
\vskip2zw\mbox{}
\end{center}%
\end{titlepage}\clearpage

 

ヘッダーのセクション名衝突回避

Re:VIEWのデフォルト設定ではヘッダに章のタイトルとセクション名が表示されますが、タイトルが長すぎるとヘッダ上で文字列が重なってしまう問題があります。

f:id:mikesorae:20210720034248p:plain
ヘッダ上の文字列衝突

ユーザビリティが下がるのであまり良い解決方法ではないかもしれませんが、弊社では review-custom.sty でsectionmarkを再定義し、ヘッダ上に表示される内容が章タイトルのみになるようにしました。

src/sty/review-custom.sty

% \renewcommand{\sectionmark}[1]{}

 

ページ番号のセンタリング

これは主にPDF版の都合ですが、ページ番号が左右にあると単一ページ表示での遷移のたびにチラついてしまうため、こちらも review-custom.sty にて中央表示になるようカスタマイズしています。

%% 通常ページ
\fancyfoot[LE,RO]{}
\fancyfoot[C]{\thepage}

 

コードブロックのデザイン修正

デフォルトのコードブロックだけでは味気なかったため、tcolorboxというパッケージを使ってデザインを変更しています。

この辺りは私もあまり詳しくないので詳細は割愛しますが、以下のような設定を review-custom.sty に追加することで、背景色やコーナーの丸み等を調整できます。

% list, cmdのデザイン変更
\usepackage[most]{tcolorbox}
\tcbuselibrary{breakable}
\renewenvironment{shaded}{
  \vspace{\baselineskip}
  \begin{tcolorbox}[breakable, enhanced jigsaw, colback=black!10!white, colframe=black!10!white, arc=1truemm, outer arc=1truemm]}
  {\end{tcolorbox}}
\renewenvironment{shadedb}{
  \vspace{\baselineskip}
  \begin{tcolorbox}[breakable, enhanced jigsaw, colback=black!80!white, colframe=black, colupper=white, sharp corners]}
  {\end{tcolorbox}}

f:id:mikesorae:20210720041211p:plain
少し丸みを帯びたコードブロック

 

コラムのデザイン修正

コラムもデフォルトでは少し無骨なデザインだったため、同様にデザイン修正を加えています。

% columnのタイトルデザイン変更
\renewcommand{\reviewcolumnhead}[2]{%
{\noindent\large ■#2}}

% columnの本体デザイン変更
\renewenvironment{reviewcolumn}[1][]{%
    \vspace{\baselineskip}
    \begin{tcolorbox}[breakable, colback=white, colframe=black!40!white, arc=1.5truemm, outer arc=1.8truemm, boxsep=5truemm]
    \setlength{\parindent}{1zw}%
    \reviewcolumnhead{}{#1}
    \vspace{1zw}
  }{%
    \end{tcolorbox}
    \vspace{\baselineskip}
  }

f:id:mikesorae:20210720051806p:plainf:id:mikesorae:20210720041356p:plain
デザイン修正前(左)とデザイン修正後(右)

 

シングルクォート問題

Re:VIEWで一番頭を悩ませたのがこのシングルクォート問題でした。 これはシングルクォートをPDF出力した際、以下のように straight quote ではなく curly quote で表示されてしまう問題です。

f:id:mikesorae:20210720041916p:plain
シングルクォート問題

Re:VIEW公式サイトのFAQに以下のようなパッチが用意されています。これでコードブロック内の問題は解決しますが @<tt>@<code> を使用した箇所は curly quote のままになっていました。

%%[ad-hoc] a trick to put upstyle single quotes literally in PDF
\begingroup
\catcode`'=\active
\catcode``=\active
\g@addto@macro\@noligs{%
  \def\review@tt@textquotesingle{{\fontfamily{\ttdefault}\textquotesingle}}%
  \def\review@tt@textasciigrave{{\fontfamily{\ttdefault}\textasciigrave}}%
  \let'\review@tt@textquotesingle
  \let`\review@tt@textasciigrave}%
\endgroup

最終的には上記FAQの少し下の、review-ext.rb を使ってPDF変換処理の前にtexファイル内の文字列を置換する方法で解決しました。

公式のパッチではシングルクォートの前後にスペースを含んでいると表示が崩れてしまったため、以下のように少し手を加えたパッチを使用しました。

src/review-ext.rb

module ReVIEW
  module LATEXBuilderOverride
    def inline_tt(s)
      super(s)
        .gsub(" ", '\ ')
        .gsub("'", '\textquotesingle ').sub(/(textquotesingle) (?!.*textquotesingle)$/, '\1')
        .gsub("`", '\textasciigrave ').sub(/(textasciigrave) (?!.*textasciigrave)$/, '\1')
    end

    def inline_code(s)
      super(s)
        .gsub(" ", '\ ')
        .gsub("'", '\textquotesingle ').sub(/(textquotesingle) (?!.*textquotesingle)$/, '\1')
        .gsub("`", '\textasciigrave ').sub(/(textasciigrave) (?!.*textasciigrave)$/, '\1')
    end
  end

  class LATEXBuilder
    prepend LATEXBuilderOverride
  end
end

 

脚注URL改行位置問題

Re:VIEWないし、TeXでは脚注の文章の改行位置が崩れる問題があります。 脚注内に、ハイフンや日本語が存在する時におかしくなるようで、調べるとRe:VIEWメンテナのkmutoさんのツイート対処法に関する2016年の記事が見つかりますが、今回じっくり検証して以下の解消方法を適応しました。

解決方法は以下のどれかになると思います。

  • @<br>{} で改行を良い感じに入れてやる
  • @<href>{http://hoge.com} でURLにする
  • urlの途中に @<embed>{|latex|\allowbreak{\}} を入れて強制改行する

f:id:vaaaaaanquish:20210719132753p:plainf:id:vaaaaaanquish:20210719132757p:plain
url改行問題対応前後

今回は、全員が書ききったmasterに対して、一気に適応する作業をしてフォーマットを調整しました。詳しくはgithubテンプレートにも説明がありますので、参考にして頂ければと思います。

 

cover画像リサイズ

cover画像はconfigのcoverimageで設定するのですが、元の画像のcanvasから1820 × 2570にリサイズしたり、コマンドを使ってリサイズしたりしてみたが上手くハマりませんでした。最終的にmacの画像リサイズで解消しました。

f:id:vaaaaaanquish:20210719132710p:plain:w400
cover画像はこんな感じにリサイズして対応しました

画像周りは配置位置などでもハマりがちなので、最後に余裕を持って直す時間を設定しておくと良いでしょう。

 

おわりに

今回は、技術書典に出るところから、執筆のコツ、テンプレートの紹介をしました。

現在開催中の技術書典11にて、エムスリーテックブック#3 絶賛発売中です。

「情報検索タスク抽出」「Krustletでラズパイクラスタ」「ハイパーカジュアルゲーム開発入門」「Rust×機械学習」「TypeScript×DDD」といったテーマで、執筆部メンバーの好きが詰まった一冊になっておりますので、是非手にとって見て下さい。

techbookfest.org

   

We are hiring!

エムスリーでは、技術が好きで仕方のないギークな仲間を募集しています! エムスリーテックブック #4を一緒に執筆しましょう!

jobs.m3.com