Hatena::ブログ(Diary)

名もないテクノ手 このページをアンテナに追加 RSSフィード

EPUB版『InDesign者のための正規表現入門』

InDesignのTips一覧

2010-09-14

[][][][]sigilの書き出すHTMLを一括修正する

以前、「iBooksでの<pre>タグの扱い」でちょっと書きましたが、HTMLをSigilでEPUB変換をすると、自分のいいように整形してしまう箇所があります。<pre>タグだけじゃくて、複数のファイルを読み込むと、参照しているCSSがひとつなのにもかかわらず、すべてのHTML分のCSSの分身を作ってしまいます。本来「base.css」しかないはずが、「base0014.css」などと追い番を付けられてしまうのでした。かこわるい。

 <link rel="stylesheet" href="../Styles/base0014.css" type="text/css" />

Nokogiriでパースして修正するようにしたら、あとあといろいろ使い回しできるかなあ、と思ってこんな感じで書いてみました。

#!/usr/bin/env ruby
# coding: utf-8

#Sigilが整形してしまうXHTMLを修正する
#1)ひとつのCSSしか参照していないのに、XHTMLの数だか増やしてしまう。→4桁の数字を削除
#2)preタグの前後に改行を入れてしまう。→preタグ内の最初と最後の改行を削除
#
require 'nokogiri'
require 'open-uri'

ARGV.each do |my_file|
	
	#XHTMLのパース
	doc = Nokogiri::XML.parse(open(my_file), nil, 'UTF-8')
	
	#ファイル名の変更(バックアプ用)
	File.rename(my_file, my_file + ".bac")
	
	#CSS名の変更
	doc.xpath("//xmlns:html/xmlns:head/xmlns:link").each do |my_css|
		tmp = my_css["href"].sub!(/\d{4}\.css$/,"\.css")
		if (tmp != nil) then
			my_css["href"] = tmp
		end
	end
	
	#preタグの改行削除
	doc.css('pre').each do |node|
		node.content = node.text.sub!(/^\n/,'')
		node.content = node.text.sub!(/\n$/,'')
	end
	
	#ファイル書き込み
	File.open(my_file, "w") {|f|
		f.puts(doc.to_xml)
	}
end

もちろん、CSS名にしたっていろいろな名付けルールがありますから(そもそも数字で管理されているとか)汎用的に使えるものではありません。ターミナル上からワイルドカード指定しても動作しますので、セクションHTMLがいくつあっても(2、300ファイルくらいなら)数秒で終わります。

これを延長して頑張れば、どこぞのアプリケーションが無責任に書き出したEPUB(腐)も修正できるかもしれません。しかしそういうHTMLをできれば見ないようにするのが賢明な人の考えることです。そもそも、ある一定のルールで書き出されたHTMLを処理する汎用的プログラムが(可能性として)書けるとしたら、それをまず先にやらなければならないのはAdobeさんでしょう。


ちなみに...

上のスクリプトはNokogiriをつかって、XMLでパースしています。HTMLでパースすると、ヘッダーとか書き換えられちゃいます。元のヘッダはDreamweaverが吐き出したものにちょっと手を加えてこんな感じ。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:lang="ja">
<head>
  <meta content="市川せうぞー" name="Author" />

  <title>タイトルほげほげ</title>
  <link rel="stylesheet" href="../Styles/base0014.css" type="text/css" />
</head>

これをHTMLでパースするとどうなるかというと...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<?xml version="1.0" encoding="utf-8"?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="市川せうぞー" name="Author">
<title>タイトルほげほげ</title>
<link rel="stylesheet" href="../Styles/base.css" type="text/css">
</head>

となってしまい、iBooks(やAdobe Digital Editions)では表示できません。

f:id:seuzo:20100914024015p:image

2010-08-13

[][][][]iBooksでの<pre>タグの扱い

html上で、<pre>タグを使ってコード行を表しました。

<pre>[\d,]+(?![\d,円])</pre>

これをEPUBにするためにSigilでコンバートしてiPhoneiBooksで見たら、こんな感じになっちゃってます。iPadで見ても同じです(Thanks! あかつきさん情報)。

f:id:seuzo:20100813115511p:image

な、なんなのこの空白は... ちなみにCSSはこんな感じ。

pre {
	font-family: "MS ゴシック", "MS Gothic", "Osaka−等幅", Osaka-mono, monospace, "ヒラギノ角ゴ Pro W3";
	background-color: #eee;
	padding-top: 0.4em;
	padding-right: 0.5em;
	padding-bottom: 0.4em;
	padding-left: 0.5em;
}

ちなみに元のHTMLをブラウザで見ると通常に見えます。

f:id:seuzo:20100813120227p:image

もちろん、Adobe Digital Editionsでも正しく表示されています。あれあれ、おかしいな... と思っていたら、Twitterで@MurakamiShinyuさんにご指摘を受けました。

Twitter / 村上真雄 MURAKAMI Shinyu: pre開始タグ直後の改行をHTMLパーサなら無視する ... Twitter / 村上真雄 MURAKAMI Shinyu: pre開始タグ直後の改行をHTMLパーサなら無視する ...

最初は、いやそんなハズはないんだが...1行で書いてるし。などと思って実際のEPUBの中身を確認。こうなっていました。

<pre>
[\d,]+(?![\d,円])
</pre>

なにやってくれてんだ、コラ! 俺さまのコード書き換えるなよ。凸

仕方ないので、エディタで直しました。

f:id:seuzo:20100813120228p:image


つまり今回の件は...

1)Sigilは何かと面倒見がよすぎてちょっとおせっかいなおばさん。

2)iBooksはまだボーヤ

3)思い込みじゃなくちゃんとコード見ろ>俺

ってことでした。