【はてぶ】コード→ブログ変換ツール

コード→ブログ変換ツール
見出しファイルとコードから、はてなブログのページを作る。
実際に本ツールで作成したページはこちら
 

 

用意するもの

  • 見出しファイル
  • ブログに載せたいコード
    • コード置き場に関して次のルール決まっている
      • ディレクトリ命名規則
      • ディレクトリ階層(深さ)
  • コード→ブログ変換スクリプト 
    • gawk が必要になるので、sudo apt-get install -y gawk でインストールしておくこと。
    • output_hatena.txt が成果物である
    • xclip でクリップボードにコピーしているので、そのままブログにペーストできる

 

見出しファイル

  • 下記 □ は全角スペースを表す
  • 「□数字.数字□見出し」を見つけたら、その見出しの直下にページ内へのリンクが挿入される
  • 以下、実例
第1章□本書を読み進める前に

□1.1□イントロダクション
□1.2□本書の概要
□1.3□Rubyについて
□1.4□Rubyのインストール
□1.5□エディタ/ IDEについて
□1.6□Rubyを動かしてみる
□1.7□本書のサンプルコードがうまく動かない場合
□1.8□この章のまとめ

第2章□Rubyの基礎を理解する

□2.1□イントロダクション
□2.2□Rubyに関する基礎知識
□2.3□文字列
□2.4□数値
□2.5□真偽値と条件分岐
□2.6□メソッドの定義
□2.7□例題:FizzBuzzプログラムを作成する
□2.8□文字列についてもっと詳しく
□2.9□数値についてもっと詳しく
□2.10□真偽値と条件分岐についてもっと詳しく
□2.11□メソッド定義についてもっと詳しく
□2.12□その他の基礎知識
□2.13□この章のまとめ

第3章□テストを自動化する

□3.1□イントロダクション
□3.2□Minitestの基本
□3.3□FizzBuzzプログラムのテスト自動化
□3.4□この章のまとめ

第4章□配列や繰り返し処理を理解する

□4.1□イントロダクション
□4.2□配列
□4.3□ブロック
□4.4□ブロックを使う配列のメソッド
□4.5□範囲(Range)
□4.6□例題:RGB変換プログラムを作成する
□4.7□配列についてもっと詳しく
□4.8□ブロックについてもっと詳しく
□4.9□さまざまな繰り返し処理
□4.10□繰り返し処理用の制御構造
□4.11□この章のまとめ

第5章□ハッシュやシンボルを理解する

□5.1□イントロダクション
□5.2□ハッシュ
□5.3□シンボル
□5.4□続・ハッシュについて
□5.5□例題:長さの単位変換プログラムを作成する
□5.6□ハッシュについてもっと詳しく
□5.7□シンボルについてもっと詳しく
□5.8□この章のまとめ

第6章□正規表現を理解する

□6.1□イントロダクション
□6.2□正規表現って何?
□6.3□Rubyにおける正規表現オブジェクト
□6.4□例題:Rubyのハッシュ記法を変換する
□6.5□正規表現オブジェクトについてもっと詳しく
□6.6□この章のまとめ

第7章□クラスの作成を理解する

□7.1□イントロダクション
□7.2□オブジェクト指向プログラミングの基礎知識
□7.3□クラスの定義
□7.4□例題:改札機プログラムの作成
□7.5□selfキーワード
□7.6□クラスの継承
□7.7□メソッドの公開レベル
□7.8□定数についてもっと詳しく
□7.9□さまざまな種類の変数
□7.10□クラス定義やRubyの言語仕様に関する高度な話題
□7.11□この章のまとめ

第8章□モジュールを理解する

□8.1□イントロダクション
□8.2□モジュールの概要
□8.3□モジュールのミックスイン(includeとextend)
□8.4□例題:deep_freezeメソッドの作成
□8.5□ミックスインについてもっと詳しく
□8.6□モジュールを利用した名前空間の作成
□8.7□関数や定数を提供するモジュールの作成
□8.8□状態を保持するモジュールの作成
□8.9□モジュールに関する高度な話題
□8.10□この章のまとめ

第9章□例外処理を理解する

□9.1□イントロダクション
□9.2□例外の捕捉
□9.3□意図的に例外を発生させる
□9.4□例外処理のベストプラクティス
□9.5□例題:正規表現チェッカープログラムの作成
□9.6□例外処理についてもっと詳しく
□9.7□この章のまとめ

第10章□yieldとProcを理解する

□10.1□イントロダクション
□10.2□ブロックを利用するメソッドの定義とyield
□10.3□Procオブジェクト
□10.4□例題:ワードシンセサイザーの作成
□10.5□Procオブジェクトについてもっと詳しく
□10.6□この章のまとめ

第11章□Rubyのデバッグ技法を身につける

□11.1□イントロダクション
□11.2□バックトレースの読み方
□11.3□よく発生する例外クラスとその原因
□11.4□プログラムの途中経過を確認する
□11.5□汎用的なトラブルシューティング方法
□11.6□この章のまとめ

第12章□Rubyに関するその他のトピック

□12.1□イントロダクション
□12.2□日付や時刻の扱い
□12.3□ファイルやディレクトリの扱い
□12.4□特定の形式のファイルを読み書きする
□12.5□環境変数や起動時引数の取得
□12.6□eval,バッククオートリテラル,sendメソッド
□12.7□Rake
□12.8□gemとBundler
□12.9□この章のまとめ

付録□Ruby on Railsの習得に向けた予備知識

□A.1□イントロダクション
□A.2□Railsの独自拡張になっている機能を理解する
□A.3□フレームワークの変化の速さに追従する
□A.4□アプリケーション設計に関する知識
□A.5□Web技術に関する知識
□A.6□データベースに関する知識
□A.7□セキュリティに関する知識
□A.8□テストの自動化に関する知識
□A.9□GitやGitHubに関する知識
□A.10□サーバや運用に関する知識
□A.11□gemに関する知識と定期的なアップデート

 

ブログに載せたいコード

以下のように「見出しファイル」の章番号 X.Y.Z のうち、X.Y までは一致させて、コードを展開しておく。
README.md が見出しファイルである。

.
├── 12.4.3
│   ├── orig.yml
│   ├── yaml_dup.rb
│   ├── yaml_parse.rb
│   └── yaml_tr.rb
├── 4.4.1
│   └── map_collect.rb
├── 4.4.2
│   ├── reject.rb
│   └── select.rb
├── 4.4.3
│   └── find.rb
├── 4.4.4
│   └── inject.rb
├── 4.4.5
│   └── amp_colon.rb
└── README.md

 

スクリプト

  • 以下は上述の見出しファイルに対応したスクリプトである
  • 35行目付近で "*.rb" ファイルを決め打ちにしているので、コード種別によって変えること
#!/bin/sh
test   -z "$1" && echo 'Error: $1 is empty' && exit 2
test ! -f "$1" && echo "Error: $1 is no such file" && exit 2
INPUT=$1
SUMMARY='下記の「プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで」を使った学習記録のページです。
本ページのプログラムは「プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで」をもとにして作成したものも多数あります。
[asin:4774193976:detail]

<script>
[:contents]
</script>
'
URL="http://www.nekochango.com/entry/ruby/book/プロを目指す人のためのRuby入門"
UUID=`uuidgen`
TMPD="/tmp/$UUID"
OUTPUT_CONTENT="$TMPD/$INPUT.content.out"
OUTPUT_APPEND="$TMPD/$INPUT.append.out"
OUTPUT="./output_hatena.txt"

rm -f $OUTPUT
mkdir -p $TMPD

echo "$SUMMARY"             >> $OUTPUT_CONTENT
echo ">>"                   >> $OUTPUT_CONTENT

# 章ごとにファイルに書き出す
for d in `find . -maxdepth 1 -type d ! -name .git ! -name . | sed 's@^./@@g' | sort -n`
do
    echo " "               >> $OUTPUT_APPEND
    h2=`echo $d  | sed 's@^./@@g'`
    xy=`echo $h2 | sed -n 's/\([[:digit:]]*\).\([[:digit:]]*\).\([[:digit:]]*\)/\1.\2/p'`
    #echo $xy
    echo "** $h2"           >> $OUTPUT_APPEND
    echo " "               >> $OUTPUT_APPEND
    for f in `find $d -type f -name "*.rb"`
    do
        b=`basename $f`
        t=`echo $b | tr -d '.' `
        uri=`echo ${URL}#${t}`
        test ! -d $TMPD/$xy/    && mkdir $TMPD/$xy
        test ! -f $TMPD/$xy/$xy && touch $TMPD/$xy/$xy
        echo "*** $b"       >> $OUTPUT_APPEND
        #echo "<b>$b</b>"    >> $OUTPUT_APPEND
        echo ">|ruby|"      >> $OUTPUT_APPEND
        cat $f              >> $OUTPUT_APPEND
        echo "||<"          >> $OUTPUT_APPEND
        echo " "           >> $OUTPUT_APPEND

        # ページ内ジャンプ用リンクを書き出す
        echo "   [$uri:title=$b]"  >> $TMPD/$xy/$xy
        #echo " "
    done
done

touch $OUTPUT_CONTENT

awk -v "TMPD=$TMPD"                         \
    -v "OUTPUT_CONTENT=$OUTPUT_CONTENT"     \
' {
    if( match( $0, /^ ([0-9]+).([0-9]+) /) ) {
        chapter = gensub(/^ ([0-9]+).([0-9]+) (.+)/, "\\1.\\2", "G", $0)
        print $0 >> OUTPUT_CONTENT
        cmd = sprintf("test -f %s/%s/%s && cat %s/%s/%s >> %s",
                        TMPD, chapter, chapter,
                        TMPD, chapter, chapter,
                        OUTPUT_CONTENT)
        #printf("%s\n", cmd)
        system(cmd)
    } else {
        #printf("%s\n", $0)
        print $0 >> OUTPUT_CONTENT
    }
}' $INPUT

echo "<<"                   >> $OUTPUT_CONTENT
echo " "                   >> $OUTPUT_CONTENT

cat $OUTPUT_CONTENT $OUTPUT_APPEND > $OUTPUT
cat $OUTPUT
cat $OUTPUT | xclip