rakeを使用して各ファイルにhtmlセクションを挿入/置換する方法は?
質問
rakeを使用して、多数の静的HTMLファイルから目次を作成しています。
質問は、rake内からすべてのファイルに挿入する方法ですか?
目的とする各ファイルには<ul id="toc">
があります。その内容全体を置き換えます。
Nokogiriなどを使用してドキュメントを解析し、DOMノードを置き換えることを考えていましたul#toc
。ただし、パーサーのDOMをHTMLファイルに書き込む必要があるという考えは好きではありません。レイアウト/インデントなどが変更された場合はどうなりますか?
考え/アイデアはありますか?または、実際の例へのリンクですか?
解決 2
私はマイク・ウッドハウスが提案したものに似たアイデアになりました。 erbテンプレートのみを使用しない(ソースファイルをruby愛好家以外でも自由に編集できるようにしたかったため)
def update_toc(filename)
raise "FATAL: Requires self.toc= ... before replacing TOC in files!" if @toc.nil?
content = File.read(filename)
content.gsub(/<h2 class="toc">.+?<\/ul>/, @toc)
end
def replace_toc_in_all_files
@file_names.each do |name|
content = update_toc(name)
File.open(name, "w") do |io|
io.write content
end
end
end
他のヒント
ファイルを.rhtmlに作り直しますか?
<ul id="toc">
は、
などのerbディレクティブに置き換えられます<%= get_toc() %>
get_toc()
は、一部のライブラリモジュールで定義されています。変換されたファイルを.htmlとして(必要に応じて別のディレクトリに)書き込むと、ビジネスに携わり、プロセスを繰り返すことができます。
または、それに来て、なぜgsub
を使用しないのですか?次のようなもの:
File.open(out_filename,'w+') do |output_file|
output_file.puts File.read(filename).gsub(/\<ul id="toc"\>/, get_toc())
end
ドキュメントを直接操作して、結果の出力を保存できます。操作を特定の要素に限定する場合、全体の構造は変更されないので問題ありません。
NokogiriやHpricotなどのライブラリは、形式が正しくない場合にのみドキュメントを調整します。 Hpricotには、よりリラックスした構文解析メソッドを持つよう指導したり、より厳密なXML / XHTML方式で操作したりできることを知っています。
簡単な例:
require 'rubygems'
require 'hpricot'
document = <<END
<html>
<body>
<ul id="tag">
</ul>
<h1 class="indexed">Item 1</h1>
<h2 class="indexed">Item 1.1</h2>
<h1 class="indexed">Item 2</h1>
<h2 class="indexed">Item 2.1</h2>
<h2 class="indexed">Item 2.2</h2>
<h1>Remarks</h1>
<!-- Test Comment -->
</body>
</html>
END
parsed = Hpricot(document)
ul_tag = (parsed / 'ul#tag').first
sections = (parsed / '.indexed')
ul_tag.inner_html = sections.collect { |i| "<li>#{i.inner_html}</li>" }.to_s
puts parsed.to_html
これにより以下が得られます。
<html>
<body>
<ul id="tag"><li>Item 1</li><li>Item 1.1</li><li>Item 2</li><li>Item 2.1</li><li>Item 2.2</li></ul>
<h1 class="indexed">Item 1</h1>
<h2 class="indexed">Item 1.1</h2>
<h1 class="indexed">Item 2</h1>
<h2 class="indexed">Item 2.1</h2>
<h2 class="indexed">Item 2.2</h2>
<h1>Remarks</h1>
<!-- Test Comment -->
</body>
</html>