同人誌sphinx電子書籍も紙書籍もキッチリ作りたい!幻想サイクルの活動では、完全オリジナルであることを活かして現物の同人誌頒布だけでなく、電子媒体での配信も意欲的に行ってきました。Unlimitedでも読めるようになっています。Unlimited>>>>>>>>>その他」となっています。思ったよりで電子版の配信が好評で驚いています。...実は、現在配信している同人誌には文字情報がありません。Illustratorで作成している都合上、文字情報を維持したままepubファイル(電子書籍形式)を作成することが手持ちのソフトでは困難だったためです。Boothで配信しているPDFは文字情報を維持できているので、コンテンツの質としてはKindle版より上なのですが利便性はそれに優るようです。※PDFでもKindleモバイルアプリで読むことは可能です実用寄りの本を書いていることもあり、せっかくなら文字検索ができる状態の本を出してもらおうとしたのがC95の新刊「泥輪事情」です。技術書典が公表を博していることもあり、1ソースから印刷用のファイルと電子書籍用のファイルを出し分けることに関するノウハウがいくらか溜まっていることは把握していたので、ITを仕事にしているものの端くれとして興味が昂ぶっていたこともあり、原稿ファイルから複数の入稿ファイルをビルドするスタイルに挑戦しました。以下、検討から出力までかなりの長文が続きますが、最終的に下記のツールでPDFの出力まで持ち込みました。2018conf.pyが含まれたリポジトリは下記のとおりです。ビルド方法はREADME参照のこと。プランがかわいく見える印刷所の料金体系の中で、非常に明快な印刷メニューと割引メニューを準備している素晴らしい印刷所です!(ダイレクトマーケティング)入稿はPDF形式です。要件はこちらのページに記載されている通り、大きく下記の3点です。出力時に上記を満たしている必要があります。A5が多いですが、評論かつ弊サークルの前例に従いB5サイズを作成するものとします。Wordじゃだめなの?ドキュメントビルドのフレームワークを使うことで、ノンブルの設定や目次の自動生成などの細かいあれこれから開放されるためです。Wordでもできる?こまけえこたあいいんだよ!あと自宅PCはずいぶん前にGoogleに入信したためOfficeが一切入っていません。あと出先でChromebookを使って執筆したいのでOfficeは(個人的には)一切使いません。フレームワーク今回のメインとなるお題です。見た限り、情報と実績が豊富なのは下記の手段。ソースは使い慣れているMarkdownをメインで使うことを前提としています。このサイトもブログもMarkdownなので、生産性という名前の慣れは抜群。md2reviewここで、最終的に「LateXを使ってPDFを出力する」という点は逃れられないことに気が付きます。若干の不安を抱えつつもネイティブにMarkdownを扱えるPandocがいいなとこの時点では考えていました。してもMarkdown記法で解決できない問題が出てきた際に、SphinxはReST、Re:ViewもRe:View記法を新たに理解する必要があるからです。新しい記法を覚えるくらいなら原稿に力を注ぎたいので、まずはPandocの参考になる情報を漁り、下記のページに行き当たります。情報をあさっている間、並行してMarkdownで構造に気を使いつつ原稿を書いていきます。http://adbird.hatenablog.com/entry/2017/01/15/010459バッチリドンピシャやんけ!!!!!!!こちらの記事を参考に、章ごとに分割した.mdファイルを準備してビルド!と思うもよく見るとTeXのテンプレートファイルを使ってそこに流し込んでいる=TeXの知識がないと細かいことができない、という点に気が付き候補から脱落。素のビルド内容でも試してみましたが、後述するSphinxに比べあまりにも味気ないので、作り込みの時間をとっていないこともあって残念ながら却下となります。Re:viewはかなり版組み向けの言語でしたが、それゆえに原稿の可読性が著しく落ちているのでやめておきました。Sphinx+RecommonMarkでオフセ本に耐えるPDFを出力するようやく本題です。Sphinxは優しいのでsphinx-quickstartを実行するだけでいい感じにディレクトリを作ってくれます。こちらは脱稿時のリポジトリです。リポジトリ構成nn_題名.mdが各章の原稿、index.rstがビルドの開始地点です。残りの設定はすべてconf.pyの中。conf_lua.pyはpLateXではなくluaLateXで出力しようとして失敗したときの名残です。本来、index.rstの内部でファイルのインポート順を決定できるため、.mdファイルにプレフィックス番号は不要なのですがPandoc用に原稿を作成した名残です。Markdown利用まずはSphinxでMarkdownを使えるようにします。RecommonMarkとAutoStructifyをインポートしてググって出てきた内容を追加します。下記の内容をconf.pyに追記・編集していきます。app.add_transform(AutoStructify)次に、.mdファイルを原稿ファイルと認識させます。'recommonmark.parser.CommonMarkParser'}この時点で、ビルドコマンドを打って.mdファイルが原稿で使えるようになりました。PowerShellだとディレクトリ内に実行ファイルがあっても明示的にパスを指定する必要があるのでめんどいです。Tableここで原稿を見ているとあることに気が付きます。テーブルが出力されていません。Markdownでサポートされている表組は対応していません。残念ですがReST記法を用いたテーブルに書き直す必要がありました。前節のAutoStructifyは、.mdファイルの中でReST記法を使えるようにしてくれます。下記のようにeval_rstで囲ったコードブロック内をReSTで解釈してくれます。==========```conf.pyでimportするだけでなく、定義も宣言しないと動作しないので注意。app.add_transform(AutoStructify)原稿の見た目はできた、出力形式が問題だ残念ながら、ここからLateXの設定と格闘することになります。conf_pyでlatex_elementsの設定内にメタデータをJSONライクに書いていくのですが、大半の設定はpreambleというLateXの設定を直書きできる箇所でレイアウトを指定します。文字サイズ、開き方向、原稿サイズ以外はほぼLateXです。'b5j'を指定すれば、LateXの設定抜きでB5サイズで出力できます。最新版のSphinxではlatex_documentsにmanualを指定した場合自動的にLatexのレイアウトがjsbook形式で出力されるので、インターネッツの海に浮かんでいるmanualとjsbookをマッピングさせる設定は不要です。'openany,twoside'は本っぽく中央の余白を大きく取るための設定となります。'manual'),]セクションの装飾を入れたところ、目次が「第0章」となってしまいますが消し方がわからないので許容しました。入稿要件の満たし方ようやく見た目の整ったPDFが出力されるようになりました。次は入稿ファイルの要件を満たしていきます。Live2018を使用した場合、デフォルトでPDFにフォントが埋め込まれます。フォント埋め込みに難航している情報が大量に検索に出てきましたが、古い情報です。IPAフォントをデフォルトで使用していますが、埋め込みフォントはkanji-config-updmap-userというコマンドを利用することで、フォントセットを簡単に切り替えることができます。これもフォント変更に難航している情報が大量に浮かんでいますが、このコマンドで一発解決します。使えるフォントセットはこちらを参考に。游ゴシック体やモリサワ、Adobeでお馴染みの小塚フォントもインストールされていれば使うことができます。実はラック出版では本文全体のPDFではなく、ページごとのPDFを03.pdfの用に単ページごとに入稿する必要があります。Sphinxで素直にビルドすると全体のPDFが出てきます。本文ページは3ページからスタートするため、目次ページのノンブルは3、本文は4ページ目からスタートしますが、Sphinxはデフォルトで目次と本文のノンブルを別物でカウントしていたためこの2つの課題を解決する必要があります。conf.pyのpreambleに設定しても動かないため、index.rstに設定を書き込みます。latexはこれまたLateX記法をrstに組み込むためのrst記法です。組版を刷る限りLateXからは逃れられないようです。ページごとのPDF出力には、Sphinxの裏のLateXの裏で動いているdvipdfmxを使います。そもそも、pLateXによるPDF出力は.tex→.dvi→.pdfという変換順になっており、副産物としてDVIファイルが生まれています。こいつを横取りして1ページづつビルドし直します。こんなコマンドをプロジェクトの/_build/latex/で打っていきます。コマンドの大量生成はGoogleスプレッドシートでやりました。'c95.dvi'...これで見た目はフォントが埋め込まれたページごとのPDFが生成されました。入稿にはPDF-X形式が基本です。カラーやらリンクが埋め込まれていないPDFファイルで、印刷の段階で事故が起きないようにするための形式らしい。RGBではなくCMYKになってます。準拠かどうか検証したり,準拠するように適切に処理したりする機能はありません。....................................LuaLatexはdvildfmxを使わずにPDFを出力でき、\usepackage[x-1a1]{pdfx}をプリアンブルに入れることでpdf-x/a1形式を出力できます。(この際に試行錯誤したときの設定ファイルがconf_lua.pyです)しかし、Sphinxで出力したtexファイルをLualatexに食わせてPDF出力したところ、思いっきり画像周りのレイアウトが崩れました。フォントの埋め込み方法が変わってしまいます。この時点でゲームオーバーと判断。最終的にはdvipdfmxで出力したモノクロPDF(埋め込み画像は予めグレースケール化済み)をラック出版さんに確認出してOKもらった上で入稿しました。オンデマンド印刷なら場合によっては問題ありませんし、コピ本ならなおさら問題なく発行できます。考えたらフォントも小塚を使ったのでAdobeの呪縛からも逃れられていませんでした。OSでも使えるようにLinux版イラレを出してくれ。簡単なソリューションはインデザに課金することです。一人で本を作るならビルド環境よりコンテンツに力を注ぎましょう。ChromeExtensioncodeタグフィードを最初に見たいんだ!Qiitaのデザイン変更に伴って、qiita.comへアクセスした際にqiita.com/trendへリダイレクトされる仕様が追加されて幾星霜。最初は面白かったのですが、やはり興味のある分野に関する記事を探す頻度のほうが高いわけでしてアクセス即タグフィードクリック生活をしていましした。時間の無駄なのでブックマークをタグフィードのURLに変更しようかと思いましたが、それでは面白くないのでChrome拡張で実装してみました。普段仕事でコードを書いているわけではないので、記法の古さや使い回しにくさ、そもそもの可読性に難がある可能性大です。オプション画面からリダイレクト先をタグフィードとタイムラインで切り替え可能です。ExtensionのAPIが全て非同期処理でコールバックを呼ぶ前提になっているので、中々苦戦しました。コールバック関数内にすべての処理を書くことで、設定取得→リダイレクト処理の順番で処理させることに成功しています。})ただし、この方法だとChrome起動時に設定が変更された場合、リダイレクト処理に反映されないのでchrome.storage.onChangedを使って変更検知のロジックを入れています。}...と記述することでnullの場合の初期値を設定できます。chrome.storage.localではなくchrome.storage.syncを使っていれば同一Googleアカウントで設定を同期できますが、テストが面倒なので実施していません。オプション用のページあまり面白みはありません。公式サンプルをちょいちょいと改造しただけです。下記のコードに加えて、「全ての投稿」も選択できるようにアップデートしました。src="options.js"></script></body></html>Chrome.storageAPIを使ってローカルストレージにオプションをオブジェクトとして保存しています。性能・HTTPS対応などなどについて無料IaaSとWordPressを越えるものを探していたところ、静的サイトジェネレーターという存在を発見。編集こそ、Markdownの作成で開発者向けではあるものの、HTML直打ちに比べるとテーマの適用やレイアウトのテンプレート化・ページングやタグページの生成などなど、圧倒的なメリットを得られる...最終的に公開されるものは静的ファイルだけなので当然性能も良いしサーバの性能もそこまで必要ない。有名なツールはいくつかあったが、生成スピードとGolangに興味があったこともあってHugoを選択。serve)コマンド打てばローカルですぐに検証できるドキュメントが割としっかりしているテーマそこそこいっぱいホスティングはNetlify静的ファイル配信にIaaS使うのはあまりにもアホらしいのでホスティングを探す。定番はS3やCloudStrageの静的WEBサイト配信機能を使うことだが、CDNが有料だったりリダイレクトを維持できなかったりと少し課題あり。そんな中Netlifyというすごいサービスがあることを知る。以下は備忘録なので細かい手順は省いて設定とやったことのみダラダラと記載していく。ExporterというWordPressプラグインを利用。WPのプラグインディレクトリに置いて、管理画面にログインして有効化する。あとは1クリックで画像と記事の.mdファイルをZIPでダウンロードできる。以上!Markdownの仕様上、広告などのインデントが深いとコード記述扱いされてしまうのでVSCodeの置換を使ってシコシコ修正する。タグやカテゴリ、パーマリンクなどはHugo用のヘッダー部分が作成されており、そこに格納されている。サンプルは以下の通り。urlは所謂パーマリンク設定がそのまま反映される。hugoでは基本的に記事が/post/記事名/になってしまうが、この項目に設定をしておけば過去のURLを維持できる。Hugoインストール、動作Chocolatey経由でGoとHugoをインストールする。siteを打てばよろしくディレクトリ構造を作ってくれる。WPからダウンロードしたMarkdownファイルを/post/へ、画像ファイルは/static/へそれぞれ移動。作業ディレクトリにconfig.tomlにWEBサイトの情報を投入して準備完了。(エクスポート時に作られたyamlファイルでも可)自分の場合はこんな感じ。serveコマンドを打てばlocalhost:1313上にサイトが展開される。リンクも実際のURLではなくlocalhostによろしく変換されてくれるので便利。hugoコマンドで/static/に実際のHTMLが生成されるが、Netlifyの場合はこの作業をGitにアップロードした後勝手にやってくれるので、ローカルで実施する必要はない。gitignoreにぶち込んでおく。テーマは/themes/ディレクトリに移動して公式からテーマファイルをCloneしてくるスタイル。Cloneしたらテーマのフォルダ名をconfig.tomlに記載すればビルドの際に記載したテーマが適用される。普段と違うテーマを試したい時はビルド時に引数で渡してやれば引数のテーマでビルドされる。Netlify用設定リポジトリのルートディレクトリにnetlify.tomlを作成してHugoのバージョンを記載する(しないと古いバージョンをビルドに使うためエラーになる)自分の場合v0.27.1を使っていたので下記の通り記載。bitbucketのどれかにリポジトリを作ってプッシュしておく。Netlifyの会員登録をして、作ったリポジトリと連携すれば自動的にサイトのビルドが実施されてデプロイまで行われる。先程ローカルにあったサイトが生成されていることを確認して終わりだ。リダイレクト公式ドキュメントによるとWEBサイトのルートに_redirectを作ってそこに記述する。Hugoの場合、サイトビルド時に変換してほしくないファイルは/static/以下に置くことになっているので、画像ファイルなどと一緒にここに配置すればOK。Bloggerの頃のパラメータと、パーマリンクを維持するために以下の設定を記入。redirect:yearなどのいかにもYYYYを検知してくれそうなプレースホルダーが用意されているが、スラッシュの間ならなんでも認識してしまう罠があった。問い合わせてみたところ仕様らしい。コンテンツと設定の移行作業はこれで全て完了。あとは独自ドメインの設定をしてDNSを切り替えればNetlifyのサーバーからサイトが配信される。Cloudflareを辞める場合、一旦ネームサーバーをGoogleに返す必要があるのでNSレコードを変更して1日待つ必要がある。DomainsでNetlifyのサーバーにCNAMEを向けて移行の全作業が終了。Cloudflare上で予めNetlifyにアクセスを向けておけば移行時間を減らせるかもしれないが、Cloudflare経由でNetlifyから配信することは推奨されていないようなのでやめておいた。Cloudflarecloudshell※この記事は前回の続きですシステム環境1クリックデプロイでGCEにWordpessをインストールした時のインストール先は下記の通り。Wordpressは/var/www/htmlディレクトリ1Apache2.4は/etc/apache2Apachedir余談だが、WEBターミナルからログインする際に自動作成されたユーザーは当然のようにsudo権限が割り振られている、便利すぎる。Encryptの証明書を使おうと思っていたのだが、どうやらCloudflareを使う場合はSSLもCloudflareで用意してくれるそうなので一本化することに。Cloudflareに登録してアカウント作成する。ウィザード画面に従って進んでいくと、どうやらドメインのネームサーバーをCloudflareのものに切り替える必要があるらしい。Domainsに切り替えて信頼性が上がったと喜んでいたところなのだが...ここで代替サービスを探すのも面倒なので言われるがままに設定。旧レジストラに登録されていた内容を自動的に反映してくれるあたりは非常に便利。DNSが切り替わった時点でCDN経由になっているため、CDN利用はこれで完了。HTTPS有効化CloudflareのHTTPS利用は「Flexible」「FULL」「FULL(Strict)」の三種類がある。Flexibleはクライアント-CDNサーバのみ、FULLはクライアント-CDN-オリジン全てHTTPSで通信するがオリジンの証明書の正当性は検査されない(オレオレ証明書でも良い)。FULL(strict)はオリジンも正式な証明書である必要がある。Flexibleで設定し、後からFULL(Strict)に切り替える方針で作業をする。管理画面でHTTPS設定を切り替えるとまずはフロントのWEBサイトがHTTPSで通信可能になる。HTTPSサイトはリダイレクトさせたいので.htaccessの出番。[R=301,L]巷ではWordPress管理画面がリダイレクトループを起こす不具合が定番になっているらしいが、起きなかったので無視。次は、CDNからオリジンサーバへの通信をHTTPSにする。Cloudflareの管理画面から証明書のCSRと秘密鍵を手に入れることができるので、それをコピーしてApacheの適当なフォルダ内に突っ込む。/etc/apache2/sites-availableにあるSSL用のデフォルト設定ファイルを見ると下記のディレクトリがお作法っぽいので同じ場所に入れる。/etc/ssl/private/gensobunya-net-private.keyApacheの設定に追加して再起動。restartCloudflareのHTTPS設定をFULLに切り替えてアクセス。この時点でうまく動かない。サーバーにはつながっているがファイルにアクセスできていないようだ...ということでWordPress用の設定を443に入れていないことに気がつく。WordPress用confに記載されていた下記の内容をコピペ。</Directory>動いた。Cloudflareの設定をFULL(Strict)に切り替えて再度アクセス。encryptなどの証明書ではなく、Cloudflare発行のオレオレ証明書だった、そりゃ警告されるわ。証明書を取るのは面倒なのでHTTPS設定はFULLで完了とすることに。以上をもって、ブログ記事を安定して投稿できる設定は終わり。1週間くらい経ったあたりで下記の問題が頭に引っかかってくる。GoogleDomainsでドメイン管理できていないのが気持ち悪いBloggerと同等のSEO・アドセンス・エディタ・画像圧縮などを出来るようにプラグインをインストールしたら管理画面が重い上記プラグインのセキュリティアップデートが面倒プレビューが重い検証環境欲しい並行作業をしすぎるとメモリ不足でMySQLが落ちる(要サーバ再起動)最後の問題が致命的で、ブログごときに監視自動化なんぞ入れたくないという決意のもとに別サービスの検討をしたところ、静的サイトジェネレーターのHugoを見つけた。次回、Hugo+Netlify編。GCPHUGOまずはBloggerをやめたかったかなり長い間Bloggerで自転車ブログを書いてきたのですが、2017年頃に不満が目立つようになってきました。エディターが変なHTMLを生成する独自ドメインのHTTPS化ができない特に前者はうっかりすると改行を全て<div>タグで出力するというおぞましい仕様。HTTPS化は当のGoogleが検索順位を落としたりしているにも関わらずBloggerが対応してくれないため。世の中常時HTTPSの流れに乗りたいという意図。サービスの対応を待っているのも嫌になったので、サービスを乗り換えることにしました。Wordpressまずは手頃で慣れているサービスとしてWordPressを検討。要件は無料で独自ドメインSSLできること、性能がそこまで落ちないこと。GCPにも興味があって並行して調べていたところ、下記の通りGCE(EC2みたいなもの)でほぼ無料でWordpressが運用できることを知りました。https://yukari-n.info/posts/gce-wordpress/自分でサーバー運用するので、当然SSLも可能。興味のあったGCPサービスということもあってまずはこれで移行することに。ブログ移行が主な目的なので、勉強はそこそこにしてWordpressは1クリックデプロイを利用してf1-microインスタンスに設置。無料枠を使うためにUSリージョンにするのを忘れない。インスタンスの性能がショボいので、最終的にはCDNを使ってほぼ全てのページをキャッシュして通信量・インスタンスの不具合を減らす方向に持っていきます。2017まずはGCPの機能に感動。SSHするのにブラウザから1クリックで証明書を自動作成してインスタンスに登録してSSHできる...さすがにWEBアプリなのでちょっと遅いが、大抵の作業は事足りる上にAndroidのConsoleアプリからも同じことができる。repository」に作成。リポジトリの認証もGoogleアカウントで完結。なんて楽なんだすごいぞGCP。extended」を使いました。使い方は下記の記事を参考に。自動で画像・タグ・記事内容・パーマリンクを取り込んでくれます。https://web-memo.fragmentnews.com/blogger-wordpress-279.htmlただし、パーマリンクで取り込んでくれるのは一番最後のファイル名のみなので予めWordPress側のパーマリンクを"/yyyy/mm/ファイル名.html"に変更しておく必要があります。絶対リンクもWordPress設定のサイトURLに置き換えられるので、移行中にIPアドレスが設定されている場合、あとでまとめて置き換えることになります。Regexを使えば一発で全記事のソースを置換できます。パーマリンク不備あとから気がついたのですが、WordPressは同じファイル名になるポストのファイル名を勝手に書き換えます。Bloggerは全角文字のみのタイトル記事は全て「blog-post.html」になるため、自分のようにパーマリンクに気を使っていないと同じファイル名が大量に生成され、blog-post-3.htmlやblog-pos4.htmlという不完全な記事が生まれます。extendedのバグなのでしょうが、普通の記事も末尾の1文字が消えていたりすることがあるので、全部見直すハメになりました。Bloggerはたまに/yyyy/mm/dd/postname.htmlというディレクトリ構成の記事もあることが発覚。こちらはどうしようもないので.htaccessに書いて対処することに。redirect念のため管理画面やリソースは除外しています。これでコンテンツは移行完了。この時点でDNSを新しいインスタンスのIPに向けて外部向けにも新サイトにアクセスを振り向ける。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。