2010-08-14

記事に埋め込むためにコードの断片を整形する

このブログの記事でコードを載せるときに使っている Ruby のプログラムだ。

整形すると言っても、実際にやっているのは HTML 系のエンティティのエスケープと行番号を振るだけ。長い行を折り畳むとか、インデントを調整するなどのような高級なことはしない。

(embed_code.rb)
 1: #!/opt/local/bin/ruby1.9 -w
 2: # coding: utf-8
 3: 
 4: require 'cgi'
 5: 
 6: source = ARGV.shift
 7: exit if ! source
 8: 
 9: def header(name)
10:   h = '<pre class="code"><code>' + "(#{File.basename(name)})"
11:   puts h
12: end
13: 
14: def footer
15:   puts '</code></pre>'
16: end
17: 
18: def scale(n)
19:   Math::log10(n).floor + 1
20: end
21: 
22: count = 1
23: lines = IO.readlines(source)
24: format = "%#{scale(lines.length)}d"
25: 
26: header(source)
27: lines.each do |code|
28:   code = CGI::escapeHTML(code.chomp)
29:   numbering = format % count
30:   STDOUT.puts "#{numbering}: #{code}"
31:   count += 1
32: end
33: footer

18 〜 20 行の scale は整数の桁数を求めるもの。行番号の出力のフォーマットに使っている。1 行目で ruby1.9 を指定しているけれど、1.8 系でも問題なく動く。整形するコードに日本語が混じっていると(コメントや文字列リテラルとして)、おかしなことになるかも。

ついでに、embed_code.rb で処理したテキストを元のコードに戻すプログラムが以下になる。ただし、embed_code.rb 出力そのものではなく、それを(HTML に組み込み)ブラウザで表示させた上でコピーしたテキストを入力にする。

以下のコード中にも、コメントとして入力サンプルを挙げてあるが、基本的には以下のフォーマットとなる。

  • 先頭行は括弧で挟まれたファイル名
  • コード本体には行番号が振られている。
  • 行番号の書式は、0個以上の空白と数字の列、その直後に「:」と空白が 1 つ。
  • それ以外の行は無視して良い。
(extract_code.rb)
 1: #!/opt/local/bin/ruby1.9 -w
 2: # coding: utf-8
 3: 
 4: # ---- input sample ----
 5: # (print_numrefs.rb)
 6: #  1: #!/opt/local/bin/ruby1.9 -w
 7: #  2: # coding: utf-8
 8: #  3: 
 9: #  4: def convert(ref)
10: #  5:   num = ref[2...-1].to_i  # Numerical reference must be "&#12345;"
11: #  6:   fs = "%c".encode("UTF-8")
12: #  7:   fs % num
13: #  8: end
14: #  9: 
15: # 10: STDIN.each do |numref|
16: # 11:   STDOUT.puts "#{numref.chomp} -> #{convert(numref)}"
17: # 12: end
18: # ----
19: 
20: outfile = nil
21: 
22: STDIN.each do |line|
23:   case line
24:   when /^\((.+)\)/              # file name
25:     outfile = File.open(Regexp.last_match[1], "w")
26:   when /^[ ]*[0-9]+:[ ](.*)/    # code body
27:     outfile.puts Regexp.last_match[1]
28:   else
29:     # nothing to do
30:   end
31: end
32: 
33: outfile.close

HTML から直接取り出すことも考えたが、ブラウザからコピーして……が実際の使い方だろうと判断した。取り出す方を自分で使うときは、以前、記事に埋めたコードが必要なのに元のファイルが見つからないときだ。なら、ユースケースは「ブラウザからコピー」になる。

github のようなリポジトリに登録してしまうのが手っ取り早いんだろうな。ちょっと大袈裟な感じがするけど。

関連リンク

0 件のコメント:

コメントを投稿