FC2ブログ

本を読む

読書やコンピュータなどに関するメモ

「明智光秀放浪記」

明智光秀放浪記 (ヤングアニマルコミックス)
重野なおき
白泉社 (2019-12-26)
売り上げランキング: 2,093

 マンガ「信長の忍び」のスピンオフで、明智光秀がだいたい信長に仕えるまでの物語。「軍師 黒田官兵衛伝」ではすでに本能寺の変が描かれ、「信長の忍び」では謀反に向かう底流として家族や家臣が路頭に迷うことへの光秀の恐怖が描かれている。そうした源流として本書は、家族思いで家臣思いの面を中心にしたストーリーとなっている。

 しかし、本書と直接関係ないけど、光秀の前半生は謎が多く、しかも本能寺の変は諸説が百出しているので、大河ドラマ「麒麟がくる」は大変だろうなあ。どう描いても「(私の中の)本当と違う!」と言う人がいそう。

「大江戸ミッション・インポッシブル 顔役を消せ」「大江戸ミッション・インポッシブル 幽霊船を奪え」

大江戸ミッション・インポッシブル 顔役を消せ (講談社文庫)
山田 正紀
講談社 (2019-11-14)
売り上げランキング: 123,506
大江戸ミッション・インポッシブル 幽霊船を奪え (講談社文庫)
山田 正紀
講談社 (2019-12-13)
売り上げランキング: 134,007

 山田正紀氏はメジャーデビュー作「神狩り」の頃から、「謎の提示がうまい」「登場するキャラがみな立ってる」「その2つをもとにどんどんストーリーが転がっていく」「ただし風呂敷は畳まない」という特徴があると思う。このへんは好き嫌いの分かれるところで、私は好きだけど。

 エンターテイメント時代劇小説の本作(2冊で完結)もそんな感じで、江戸の闇を統べる川衆と陸衆の争いを中心に、個性的な登場人物が登場するのが特徴だ。「顔役を消せ」のほうは題名どおりミッションもの展開になるんだけど、「幽霊船を奪え」のほうはまあ幽霊船があまり重要じゃないなあとか。

 必殺シリーズとか「サイコ」とか過去の有名作品のオマージュがいろいろ。“かま”の笑い方と飄々として謎めいたキャラは、ちょっと「まほろ」の行天っぽい。だいぶ剣呑だけど。

台割のExcelファイルをRubyで自動生成する方法の入口

 このエントリーは「書き手と編み手の Advent Calendar 2019」の12月4日分の記事です。

 紙の書籍を編集や制作した経験のある人にとって、台割はおなじみのものです。なお、ここでは台割とは何かについては省略します。

 自分の見てきたIT系出版の世界では、台割をExcelで作ることが多いようです。台割では、最初のほうの章のページ数が変わったりすると、それ以降をずらす必要があって大変です。そのため、Excelのマクロなどを使って自動化する人もけっこういるのではないかと思います。

 ここでは、Ruby言語のコードを使って台割のExcelファイル(.xlsxファイル)を生成するのを目標に、その方法の入口を解説します。あくまで入口であって、台割が完成するところまでは説明しません。

 つまりは、「ただツールやライブラリの使い方を紹介するだけ」のエントリーってやつです。

注意

  • 対象は広義の平綴じ(無線綴じなどを含む、中綴じでない書籍)用の台割です
  • Ruby言語の解説は割愛します
  • Ruby処理系やライブラリのインストール方法にまつわることについても割愛します

ステップ0:axlsxをインストールする

 Rubyで.xlsxファイルを生成するには、axlsxというライブラリを使うと便利です。

 gemやbundleなどで「axlx」をインストールします。ただし、執筆時点では、axlsxのリリース版だと最近のRubyでは警告が出るので、「3.0.0.pre」版を指定してインストールします。

$ gem install axlsx -v 3.0.0.pre

 axslxはnokogiriというライブラリに依存しているので、それまでにインストールされていなければいっしょにインストールされます。

 なお、axlsxからフォークしたaxlsx-altというライブラリもあるようですが、私は未評価です。

ステップ1:空の.xlsxファイルを出力する

 とりあえず、何もせずに空の.xlsxファイルを出力してみます。以下のような内容のsample.rbファイルを作ります。

require 'axlsx'

Axlsx::Package.new do |pkg|
  pkg.serialize('out.xlsx')
end

 Axlsx::Package#serializeがファイル出力です。

 これを実行すると、out.xlsxというファイル名の、何も書かれていない.xlsxファイルが作られます。

$ ruby sample.rb

ステップ2:1行書き込む

 out.xlsxを出力するプログラムに、表に1行を追加するコードを追加します。

require 'axlsx'

Axlsx::Package.new do |pkg|
  wb = pkg.workbook
  wb.add_worksheet(name: 'シート1') do |sheet|
    sheet.add_row(['折', '通', nil])
  end

  pkg.serialize('out.xlsx')
end

 Axlsx::Package#workbookでExcelのブックを取得し、そのブックのadd_worksheetでExcelの(ワーク)シートを作成します。そして、そのシートのadd_rowで“折”と“通”と空の3つのセルがある行を追加します。

 生成されたExcelファイルは、こんな感じです。

ステップ2の結果

ステップ3:列幅を指定する

 このままでは、どの列も同じデフォルトの幅なので、列幅を変更します。各列の幅は、シートのcolumn_widthsで指定します。

    sheet.column_widths(4, 4, 20)

 column_widthを呼び出すのは、add_rowより後のほうがいいようです。追加後のコードは以下のとおりです。

require 'axlsx'

Axlsx::Package.new do |pkg|
  wb = pkg.workbook
  wb.add_worksheet(name: 'シート1') do |sheet|
    sheet.add_row(['折', '通', nil])
    sheet.column_widths(4, 4, 20)
end

  pkg.serialize('out.xlsx')
end

 生成されたExcelファイルは、こんな感じです。

ステップ3の結果

ステップ4:セルのスタイルを指定する

 ここまでで書き込んでいる1行は、表のタイトル行にします。そのため、文字は太字で、セルは罫線で囲んだものにします。

 まず、ブックに対してスタイルを定義します。ここでは、表の通常行でも使うように、罫線の形式を指定するHashを変数bordersで参照できるようにしておきます。

  styles = wb.styles
  borders = { style: :thin, color: '000000' }
  title_style = styles.add_style(b: true, border: borders)

 add_rowを記述を変更して、定義したスタイルの指定を追加します。

    sheet.add_row(['折', '通', nil], style: title_style)

 これらを反映したコードは以下のとおりです。

require 'axlsx'

Axlsx::Package.new do |pkg|
  wb = pkg.workbook

  styles = wb.styles
  borders = { style: :thin, color: '000000' }
  title_style = styles.add_style(b: true, border: borders)

  wb.add_worksheet(name: 'シート1') do |sheet|
    sheet.add_row(['折', '通', nil], style: title_style)
    sheet.column_widths(4, 4, 20)
  end

  pkg.serialize('out.xlsx')
end

 生成されたExcelファイルは、こんな感じです。

ステップ4の結果

ステップ5:通常行を追加する

 タイトル行だけでなく通常行も追加しましょう。

 まず通常行のスタイル定義を追加します。

  body_style = styles.add_style(alignment: { vertical: :top }, border: borders)

 タイトル行の定義から太字指定を抜いて、垂直位置の指定を追加したものです。

 通常行もadd_rowで追加します。実用性はありませんが、ここでは内容は決めうちで。

    sheet.add_row([1, 1, '本扉'], style: body_style)
    sheet.add_row([1, 2, '商標'], style: body_style)
    sheet.add_row([1, 3, '前書き'], style: body_style)
    sheet.add_row([1, 4, nil], style: body_style)
    sheet.add_row([1, 5, nil], style: body_style)
    sheet.add_row([1, 6, '目次'], style: body_style)
    sheet.add_row([1, 7, nil], style: body_style)
    sheet.add_row([1, 8, nil], style: body_style)
    sheet.add_row([1, 9, nil], style: body_style)
    sheet.add_row([1, 10, nil], style: body_style)
    sheet.add_row([1, 11, '1章'], style: body_style)
    sheet.add_row([1, 12, nil], style: body_style)
    sheet.add_row([1, 13, nil], style: body_style)
    sheet.add_row([1, 14, nil], style: body_style)
    sheet.add_row([1, 15, nil], style: body_style)
    sheet.add_row([1, 16, nil], style: body_style)

 これらを追加したコードは以下のとおりです。

require 'axlsx'

Axlsx::Package.new do |pkg|
  wb = pkg.workbook

  styles = wb.styles
  borders = { style: :thin, color: '000000' }
  title_style = styles.add_style(b: true, border: borders)
  body_style = styles.add_style(alignment: { vertical: :top }, border: borders)

  wb.add_worksheet(name: 'シート1') do |sheet|
    sheet.add_row(['折', '通', nil], style: title_style)
    sheet.add_row([1, 1, '本扉'], style: body_style)
    sheet.add_row([1, 2, '商標'], style: body_style)
    sheet.add_row([1, 3, '前書き'], style: body_style)
    sheet.add_row([1, 4, nil], style: body_style)
    sheet.add_row([1, 5, nil], style: body_style)
    sheet.add_row([1, 6, '目次'], style: body_style)
    sheet.add_row([1, 7, nil], style: body_style)
    sheet.add_row([1, 8, nil], style: body_style)
    sheet.add_row([1, 9, nil], style: body_style)
    sheet.add_row([1, 10, nil], style: body_style)
    sheet.add_row([1, 11, '1章'], style: body_style)
    sheet.add_row([1, 12, nil], style: body_style)
    sheet.add_row([1, 13, nil], style: body_style)
    sheet.add_row([1, 14, nil], style: body_style)
    sheet.add_row([1, 15, nil], style: body_style)
    sheet.add_row([1, 16, nil], style: body_style)
    sheet.column_widths(4, 4, 20)
  end

  pkg.serialize('out.xlsx')
end

 生成されたExcelファイルは、こんな感じです。

ステップ5の結果

ステップ6:セルを連結する

 折(台)を示すセルは折(台)ごとに共通です。そのため、セルを連結してみます。

 シートのmerge_cellsを呼び出します。

    sheet.merge_cells('A2:A17')

 これらを追加したコードは以下のとおりです。

require 'axlsx'

Axlsx::Package.new do |pkg|
  wb = pkg.workbook

  styles = wb.styles
  borders = { style: :thin, color: '000000' }
  title_style = styles.add_style(b: true, border: borders)
  body_style = styles.add_style(alignment: { vertical: :top }, border: borders)

  wb.add_worksheet(name: 'シート1') do |sheet|
    sheet.add_row(['折', '通', nil], style: title_style)
    sheet.add_row([1, 1, '本扉'], style: body_style)
    sheet.add_row([1, 2, '商標'], style: body_style)
    sheet.add_row([1, 3, '前書き'], style: body_style)
    sheet.add_row([1, 4, nil], style: body_style)
    sheet.add_row([1, 5, nil], style: body_style)
    sheet.add_row([1, 6, '目次'], style: body_style)
    sheet.add_row([1, 7, nil], style: body_style)
    sheet.add_row([1, 8, nil], style: body_style)
    sheet.add_row([1, 9, nil], style: body_style)
    sheet.add_row([1, 10, nil], style: body_style)
    sheet.add_row([1, 11, '1章'], style: body_style)
    sheet.add_row([1, 12, nil], style: body_style)
    sheet.add_row([1, 13, nil], style: body_style)
    sheet.add_row([1, 14, nil], style: body_style)
    sheet.add_row([1, 15, nil], style: body_style)
    sheet.add_row([1, 16, nil], style: body_style)
    sheet.column_widths(4, 4, 20)

    sheet.merge_cells('A2:A17')
  end

  pkg.serialize('out.xlsx')
end

 生成されたExcelファイルは、こんな感じです。

ステップ6の結果

その先

 このエントリーでは、1折(台)ぶんだけ決めうちで台割を作りました。これだけでは実用性はありませんが、作り方によっていろいろ楽ができるようになります。

 たとえば、章とそのページ数を記述したデータを用意して、そこから台割を生成するという応用が考えられます。また、章ごとのPDFファイルからページ数をカウントして台割を生成するという応用も考えられるでしょう。

 さらには、文字サイズや表のレイアウト、修飾スタイル、表本体以外の記載事項など、いろいろ工夫できる要素もあります。

 このエントリーがそのような自動化のヒントになれば幸いです。

 | HOME | 

Categories

Recent Entries

Recent Comments

Recent Trackbacks

Appendix

emasaka

emasaka

フリーター。
連絡先はこのへん

Monthly