下のページのEmacs Org-Babelのイントロダクションページを和訳しました。

http://orgmode.org/worg/org-contrib/babel/intro.html


例によってざっくり雰囲気だけで結構いい加減です。


今のところ29の言語に対応しているらしいです。

http://orgmode.org/worg/org-contrib/babel/languages.html


思ったことは、

・何箇所か書いてあるとおりにやっても上手く動かなかった・・・

・Orgモードで文章書いてコードを埋め込めるからコメントつけるよりは見やすいのかな・・・?

・実行速度が・・・とかいらない心配してたけど、コマンド一発でソースだけ抜き出して別のファイルに出力できるらしい。

・Rって触ったことなかったけど、簡単にグラフとか出力できて面白そう

・これを使うとEmacs Lispは本当に必要なところだけ書いて、処理の部分は別の言語で括弧フリーになれる?


一番面白いと思ったのは、Emacsの初期化ファイルをOrgで管理してしまおう!という内容です。

init.elとかにはOrgファイルへのロードパスを書いて、カスタマイズ部分を書いたOrgファイルへを読み込む関数を書くだけ。


後はOrgファイルでアウトラインを使ってわかりやすく整理しましょう!という試みです。


つまり今まではこんな感じでコメントアウトして大まかに区切ってたのを、


くらいまーず はい


こんな感じでOrgモードを使ってわかりやすく整理できます。


くらいまーず はい

上はOrgモードだからフォントロックがかかってないけど、

"C-c '"を押せばちゃんとLispモードで別バッファが開いて編集できます。

くらいまーず はい


なんか便利そうじゃないですか??


使い方とか例は、starter-kitを覗いてみると良いかもしれません。

https://github.com/eschulte/emacs-starter-kit


ではここから和訳です。


* Introduction
Babelはプログラミング言語のソースコードと非常に親和性が高く、
コードの評価といった様々な機能を持った素晴らしいOrg-modeのエクステンションです。


Org-modeはEmacsのメジャーモードの一つで、プレーンなテキスト上で非常に様々な事ができます。
もしあなたがOrg-modeに馴染みがないなら、読み進める前にOrg-modeのHPを読んでみてください。


その名が示すとおり、Babelは多くの異なったプログラミング言語を評価できます。
テキスト、表、グラフィックといったコードの実行結果は、他のコードブロックで再利用したり、
Org-modeの強力なデータ出力機能によってひとまとめのファイルに出力することができます。

Babelによって、Org-modeのコードブロックは以下のように補強されます。


- コードブロックの対話的・ファイル上での結果出力
- パラメーター化されたコードブロックを、他のブロックから呼び出せます。
- コードの実行結果を編集できる形で出力できます。


* Overview
Babelには幾つかの入り口があって、それぞれに新しい発見があるでしょう。
どこから始めるかは人それぞれです。


- Org-modeで"src"ブロックを使う。
 もしあなたがOrg-modeの中で"src"ブロックを使うことに慣れていなくて、
 異なるバッファの間を行ったり来たりしているなら、
 まずは"src"ブロックについてOrg manualについて調べてください。
 試してみて理解できたら、ここに戻って来てください。


- コードの評価
 Babelの肝は、Org-modeの"src"ブロックの中でコードを評価できることです。
 他のブロックや表から入力を受け取ったり、別のブロックに結果を渡すことができます。
 詳しい説明は下で行います。


- 読み書き自由自在なプログラミング
 もし普段プログラミングをするときにコマンドライン等を使っているなら、
 Org-modeのファイル中にブロックを作って、コードを書いてみてください。
 それからBabelの機能を使って、純粋なコードをOrgファイルから抜き出してみましょう。


こういったユースケースの全ては、Org Manualの"Working with Source Code"に網羅されています。


* Initial Configuration
もしあなたがEmacsを使っているなら、Babelを始めるのは簡単です。


1. Org-modeは絶対に最新版にアップデートしてください。Org-mode7.0ではBabelはOrg-modeに含まれています。


2. あなたがBabelで評価したいプログラミング言語をアクティベートしてください。
  Emacs Lispは最初からアクティブになっています。


3. 変更したDotEmacsを評価してください。


* Code Blocks
** Code Blocks in Org
Babelとは要はOrg-mode中のコードブロックのことです。
もしあなたがOrg-mode中で"src"ブロックと呼んでいるコードブロックについてよく知らないなら、
読み進める前にOrg-modeマニュアルを読んでみてください。


コードブロックはOrg-modeのファイルであればどこにでも挿入できます。
直接打ち込むこともできますが、"org-edit-src-code"の機能を使うほうが簡単でしょう。
通常は"C-c '"にキーバインドされています。
"C-c '"によって、コードブロックを入力するための適切なメジャーモードの新しいバッファが開きます。


#+begin_src language org-switches
body
#+end_src


例えばrubyのコードブロックはこんな感じになります。


#+begin_src ruby
require 'date'
"This file was last evaluated on #{Date.today}"
#+end_src


** Code Blocks in Babel
Babelはコードブロックに新しい要素を追加します。
基本的な構成は下記のようになります。


#+begin_src language org-switches header-arguments
body
#+end_src


- language
コードブロックに書くプログラミング言語の種類です。
変数は"org-babel-interpreters"のメンバーである必要があります。


- header-arguments
header-argumentsは評価や結果の出力の色々な方法をコントロールします。
詳しくはマニュアルを参照してください。


- body
評価対象のソースコードを記述します。


"C-c '"のキーバインドは是非覚えてください。
このキーバインドで"org-edit-src-code"を呼び出すことにより、
ソースコードをその言語のメジャーモードの新しいバッファ上で編集できます。


* Source Code Execution
Babelはshell,python,Rといったインタープリター言語を評価します。
もちろんここの言語は別途自分でインストールしておく必要があります。


3つの異なる言語でコードブロックを書いた例を紹介します。
もしあなたがEmacs上でこの文章を
見ているなら、
ブロック中にカーソルを移動して"C-c C-c"を押してコードを実行してみてください。


** Code Example
*** Ruby
- Org-mode中の記述


#+begin_src ruby
"This file was last evaluated on #{Date.today}"
#+end_src


- コードのHTMLへの出力結果


"This file was last evaluated on #{Date.today}"


- 評価結果をHTML へ出力


This file was last evaluated on 2009-08-09


*** Shell
- Org-mode中の記述


#+begin_src sh
echo "This file takes up `du -h org-babel.org |sed 's/\([0-9k]*\)[]*org-babel.org/\1/'`"
#+end_src



echo "This file takes up `du -h org-babel.org |sed 's/\([0-9k]*\)[]*org-babel.org/\1/'`"


- 出力結果をHTMLへ出力


This file takes up 36K


*** R
ファイルの中で一番良く使われている単語の統計を取るプログラム


- Org-mode中の記述


#+begin_src R :colnames yes
words <- tolower(scan("intro.org", what="", na.strings=c("|", ":")))
t(sort(table(words[nchar(words) > 3]), decreasing=TRUE)[1:10])


** Capruring the Results of Code Evaluation
Babelにはコードの評価結果をキャプチャーするために、
"functional mode”"scripting mode"という2つのモードがあります。
どちらのモードを利用するかはheader argumentの":results"で決定できます。


*** :results value(functional mode)
"functional mode"では、コードブロックは値を返す関数として機能します。
コードブロックから出力された値は、他の言語で書かれたブロックへの入力として使用できます。
つまりBabelはメタプログラミング言語として機能します。


もしそのコードブロックが、ベクトルや配列といったデータを返すなら、バッファ中ではOrg-modeの表データとなります。


例えばpythonで書かれた以下のコードブロックの出力について考えてみましょう。


import time
print("Hello, today's date is %s" %time.ctime())
pring('Two plus two is ')
return 2 + 2


functional modeでは一番下の"retunr 2 + 2"の結果のみが出力されます。


*** :results output(scripting mode)
scripting modeでは、Babelはコードブロックのファイル出力をキャプチャーしてバッファ中に書き出します。
これが"scripting mode"と呼ばれるのは、コードブロックが一連のコマンドを含んでいて、それぞれの結果が返されるからです。
functional modeと異なり、コードブロックそのものは値を返しません。

以下のコードをscriptiong modeで評価した場合の結果を考えてみましょう。


import time
print("Hello, today's date is %s" %time.ctime())
pring('Two plus two is ')
return 2 + 2


scripting modeではpythonがstdoutに送ったテキストが返されます。
一番最後の"2+2"はpring()ではないので、"4"は結果には現れません。


** Session-based Ecaluation
python,R,shellといった幾つかの言語は、Emacsの裏でインタラクティブな処理を動かしておくことが出来ます。
つまり異なるプログラミング言語感でデータをやり取りする環境を作ることが出来ます。
Babelでは":session"ヘッダーを使ってこのような環境での評価をサポートします。


もしheader-argumentとして何か値が渡された場合、それはセッション名として使用されます。
これによって、逆に同じ言語を使って幾つかのセッションをひとつのファイル内でシミュレートすることが出来ます。


"Session-base"の評価はプロトタイプの評価やデバッグに非常に有効です。
"org-babel-pop-to-session"はセッションバッファーへの切り替えに使われます。

** Arguments to Code Blocks
Babelはコードブロックをパラメーター化出来ます。
例えば引数をコードブロックに渡して関数の様に扱うことが出来ます。
引数は"functional mode" "scripting mode"どちらのコードブロックにも渡すことが出来ます。


*** Shiple example of using a code block as a function
まず非常に簡単な例を見てみましょう。
以下のコードブロックはpythonを使って引数を2乗する関数を定義しています。


#+source: square(x)
#+begin_src python
return x*x
#+end_src


このブロックを下のように呼び出すことが出来ます。


#+call: square(x=6)


*** A more comples example using an Org-mode table as input
この例ではフィボナッチ数列を求める関数をEmacs Lispで書いてみます。
関数はひとつの引数を取り、今回はOrg-modeのテーブルからその引数を与えてみます。


まず関数に渡す引数の一覧を下記のように書きます。


#+tblname: ficonacci-inputs
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 |


次にEmacs Lispでフィボナッチ数列を求める関数を書きます。


#+srcname: ficonacci-seq(fib-inputs = ficonacci-inputs)
#+begin_src emacs-lisp
(defun fibonacci (n)
(if (or (= n 0) (= n 1))
n
(+ (fibonacci (- n 1)) (fibonacci (- n 2)))))
(mapcar (lambda (row)
(mapcar #'fibonacci row)) fib-inputs)
#+end_src


上のコードブロックを評価すると、下記のように値が返されます。


#+results: ficonacci-seq
| 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 |
| 1 | 3 | 8 | 21 | 55 | 144 | 377 | 987 | 2584 | 6765 |


*** In-line Code Blocks
コードは下記の様に書くことで一行から評価できます。


src_python[:sesion]{10*x}


この例で"x"はこのセッション中で既に定義済みの変数です。


*** Code Block Body Expansionーーーよく分からん
Babelは評価する前にコードを展開することが出来ます。


*** A Meta-programming Language for Org-mode
ある言語で書かれたプログラムの結果を別の言語のコードに渡したり、
ファイル中で表にしたり出来るので、Babelはメタプログラミング言語として使えます。


Babelでは様々な言語で書かれた関数を一緒に使うことが出来ます。
あなたは各々の言語が一番得意な分野を使うことで、様々な言語をひとつのファイル上でミックスできます。


例えば、シェルでシステムのサイズを書きだして、それをRでグラフにしてみましょう。

1. shellを使ってホームディレクトリのリストをサイズと共に書き出すコードブロックを作ります。
Babelは自動的に結果を表に整形してくれます。


#+srcname: directories
#+begin_src sh :results replace
cd ~ && du -sc * |grep -v total
#+end_src

#+results: directories
| 4 | Desktop |
| 1388 | Documents |
| 3868 | Downloads |
| 4 | Music |
| 404 | Pictures |
| 4 | Public |
| 4 | Templates |
| 4 | Videos |
| 4 | examples.desktop |
| 4 | missfont.log |


2. 一行で書かれたRのコードを書いて、上の表を円グラフにします。


#+srcname: directory-pie-chart(dirs = directories)
#+begin_src R :session R-pie-example :file ~/.emacs.d/dires.png
pie(dirs[,1], labels = dirs[,2])
#+end_src

#+results: directory-pie-chart
[[file:~/.emacs.d/dires.png]]


くらいまーず はい


* Using Code Blocks in Org Tables
コードブロックの引数として表のデータを渡したり、その結果を表として保存する他、
BabelはOrg-modeの表と共に使うことも出来ます。


** Example 1: Data Summaries Using R
簡単な例として、幾つかの数字の平均値を表に代入してみましょう。
まずデータを幾つか作ります。
以下のソースブロックは0~1の間のランダムな数字を5つ生成します。


#+srcname: tbl-example-data()
#+begin_src R
runif(n=5, min=0, max=1)
#+end_src

#+results: tbl-example-data
| 0.274583599995822 |
| 0.979716712608933 |
| 0.902911761542782 |
| 0.958305723499507 |
| 0.598920254968107 |


次に平均値を計算するブロックを作ります。


#+srcname: R-mean(x)
#+begin_src R
mean(x)
#+end_src

#+results: R-mean


最後に表を作って計算した値を代入します。
これはsbe(source block evaluate)マクロを使って行います。


#+tblname: summaries
| mean |
|------------------|
| 0.74288761052303 |
#+TBLFM: @2$1='(sbe "R-mean" (x "tbl-example-data()"))


** Example 2: Babel Test Suite
Babelを開発しているとき、私たちはOrg-modeの表を使って一連の実装テストを行っていました。
表の上で"C-u C-c C-c"と打つだけですべてのテストが実行され、表中のデータが更新されて、
テストをパスしたかどうかが一目でわかりました。

テストに使ったサンプルはこんな感じです。


簡単なテストをすることで、使いたい言語の設定が正しく出来ているか確認できます。


注)表が崩れているからわかりにくいですが、各コードブロックの評価結果が、

"expected"の列の値と等しければ"results"の列に"pass"を挿入しています。


#+TBLNAME: org-babel-tests
| functionality | block | arg | expected | results | |
|------------------+--------------+-----+-------------+-------------+------|
| basic evaluation | | | | | pass |
|------------------+--------------+-----+-------------+-------------+------|
| emacs lisp | basic-elisp | 2 | 4 | 4 | pass |
| shell | basic-shell | | 6 | 6 | pass |
| ruby | basic-ruby | | org-babel | org-babel | pass |
| python | basic-python | | hello world | hello world | pass |
| R | basic-R | | 13 | 13 | pass |
#+TBLFM: $5='(if (= (length $3) 1) (sbe $2 (n $3)) (sbe $2)) :: $6='(if (string= $4 $5) "pass" (format "expected %S but was %S" $4 $5))



#+srcname: basic-elisp(n)
#+begin_src emacs-lisp
(* 2 n)
#+end_src


#+srcname: basic-shell
#+begin_src sh :results silent
expr 1 + 5
#+end_src


#+srcname: basic-ruby
#+begin_src ruby :results silent
"org-babel"
#+end_src


#+srcname: basic-python
#+begin_src python :results silent
return "hello world"
#+end_src

注)サイトに書かれているコードそのままだと上手くいきませんでした。

pythonのバージョンの問題??


#+srcname: basic-R
#+begin_src R :results silent
b <- 9
b + 4
#+end_src


* The Library of Babel
上の例でも見たように、一度ブロックを定義すると"lob"を使っていつでも呼び出せます。


#+lob: square(x=6)


しかしすべてのOrg-modeバッファで使い回したいブロックがある場合はどうなるのでしょうか?


現在のバッファに加えて、BabelはBabelのLibraryから関数定義されたコードブロックを探します。
これはユーザーが共通の方法で扱える、拡張可能な一連のコードブロックの塊です。
Library of Babelの使用方法のひとつは、R,gnuplotなどを使ってデータをグラフ化する幾つかの方法を提供することでしょう。


もしあなたが他のOrg-modeユーザーにも便利だと思える機能を実装したら、
それをBabelのライブラリーに加えることを考慮してください。
同様にもしBabelを使っていて困ったことがあったらいつでも質問してください。
他のユーザーが解決策を持っているかもしれません。


"org-babel-lob-ingest"を使用することによって、どんなOrg-modeのファイルからでもコードブロックを読み込むことが出来ます。


(org-babel-lob-ingest "path/to/file.org")


* Literate Programming
BabelはプログラムをOrg-modeのファイルの中に記述することによって、文芸的プログラムをサポートしていると言えます。
Org-modeのファイルは人間が使うためにHTMLやLaTxXに出力でき、コンピューターが解釈するためにソースだけを抽出できます。
こういった作業をサポートするためにBabelはOrg-modeのドキュメント出力機能に依存しています。
以下の例はBabelにおけるソース抽出のプロセスを紹介します。


** Simple Literate Programming Example(Noweb syntax)
ソースの抽出(外部ファイルへのソースの書き出し)は専用の"Tangle header arguments"によってコントロールされます。

以下のコードは"org-babel-tangle"関数が以下にして複数のコードをひとつのファイルにまとめるかのデモです。

以下3つのコードのうち、最初の2つは抽出(tangle)用の引数を持たないのでファイルへの出力は行われません。
ファイルへの出力は、"tangle"用引数を持つ3番目のコードブロックで行われます。


#+srcname: hello-world-prefix
#+begin_src sh :exports none
echo "/--------------------\\"
#+end_src


#+srcname: hello-world-postfix
#+begin_src sh :exports none
echo "\---------------------/"
#+end_src


#+srcname: hello-world
#+begin_src sh :tangle hello2 :exports none :noweb yes
<<hello-world-prefix>>
echo "| hello world |"
<<hello-world-postfix>>
#+end_src

注)なんか実行しても結果が入るテキストが出来るだけで、シェルのソースコードは出来ないんだけど・・・?


付け加えると、<<>>でブロック名を囲む事で、そのブロックの結果を挿入できます。
また引数も与えることが出来ます。


<<example-block(a=9)>>


** Emacs Initialization with Babel
BabelはEmacsの初期化ファイルをOrg-modeに埋め込む手段も提供します。
"org-babel-load-file"関数を使うことで、init.elや.emacsを使うのと同じようにOrg-modeのファイルから、
Emacs Lispコードを読み込むことが出来ます。


これによってOrg-modeのアウトライン機能、タグ、メモ、HTMLへのエクスポートなどの素晴らしい機能を使って、
あなたの初期化ファイルをメンテナンスすることが出来ます。


この方法を試したり、あるいは例を見たいならPhil Hagelbergによる素晴らしいemacs-starter-kitを試してみてください。

使い方を簡単に説明すると、以下の5ステップを実行するだけです。


1. ホームディレクトリに".emacs.d"という名前のディレクトリを作ります。


2. .emacs.dの中に"src"ディレクトリを作って、Org-modeの最新版をダウンロードしてきます。


3. ".emacs.d"にinit.elを作り、簡単なEmacs Lispコードを書きます。
  Orgへのロードパス設定と、初期化データが書かれたorgファイルを読み込むコードだけが書かれています。


4. Org-modeファイルの中にEmacs Lispブロックを埋めこんで、カスタマイズします。



以上です。

あと参考になりそうなOrgマニュアルのページ

http://orgmode.org/manual/Working-With-Source-Code.html#Working-With-Source-Code

http://orgmode.org/manual/Literal-examples.html

http://orgmode.org/worg/org-contrib/babel/uses.html

これを訳すかどうかは考え中です。


5. カスタマイズした内容を反映させるために、Emacsを再起動します。
- コードをHTMLへ出力 #+end_src