2017-10-26 ,

org-modeのコードブロック(Babel)の使い方

基本的な使い方(コードブロックの評価とエクスポート)

ソースコードブロックは #+BEGIN_SRC で始まり #+END_SRC で終わる。

次の例は、Emacs Lispで1+2+3を計算するコードをOrg文書に埋め込んでいる。

Emacs Lispで1+2+3を計算するには次のように書きます。

#+BEGIN_SRC emacs-lisp
(+ 1 2 3)
#+END_SRC

#+BEGIN_SRC#+END_SRC は手で打たなくても org-insert-structure-template コマンドで挿入できる。デフォルトでは C-c C-, の後に s を打てば良い。

#+BEGIN_SRC の直後には言語名を指定する(有効な言語は Babel: Languages 等を参照のこと)。

このソースコードブロックの上で C-c C-c を押すとコードを評価(実行)するかどうか聞いてくる。yesを選択するとコードが評価されてコードブロックの下に結果が挿入される。(評価できる言語は org-babel-load-languages 変数であらかじめ設定する)

Emacs Lispで1+2+3を計算するには次のように書きます。

#+BEGIN_SRC emacs-lisp
(+ 1 2 3)
#+END_SRC

#+RESULTS:
: 6

このOrg文書を C-c C-e でLaTeXやHTML等でエクスポートすると、ソースコードのリストと実行結果がペアで出力される。

また、行の中にソースコードを埋め込むことも出来る(インラインコードブロック)。例えば次のように書ける。

Emacs Lispで2*3を計算するには src_emacs-lisp[:exports code]{(* 2 3)} のように書く。
結果はもちろん src_emacs-lisp[:exports results :eval no-export]{(* 2 3)} {{{results(=6=)}}} である。

src_言語名[ヘッダー引数]{コード本体} の形で文章の中にソースコードを記述できる。インラインコードブロックの上でも C-c C-c を押すとコードが評価され、結果はその右に挿入される。エクスポートすると指定されているオプション(ヘッダー引数)に従ってコードそのものが出力されたり結果のみが出力されたりする。

コードブロックに関連するキー操作

(場所)キー操作 関数 動作
C-c C-, org-insert-structure-template 各種ブロック(#+BEGIN_ で始まり #+END_ で終わる)を挿入する。
(コードブロック上で) C-c ‘ org-edit-src-code コードの編集。編集バッファから出るには再度C-c ‘を押す。 (公式マニュアル: Editing source code – The Org Manual)
(コードブロック上で) C-c C-c org-babel-execute-src-block コードを実行する。 (公式マニュアル: Evaluating code blocks – The Org Manual)
(コードブロック上で) C-c C-v j org-babel-insert-header-arg ヘッダー引数を挿入する。
(orgファイル内で) C-c C-e org-export-dispatch エクスポートメニューを表示する。htmlでエクスポートしてブラウザで開くには続けてh oと打つ。エクスポート時に各コードブロックは評価される。

その他コードブロックに関する様々なキーが定義されている。(公式マニュアル: Key bindings and Useful Functions (The Org Manual))

基本構文

(公式マニュアル: Structure of Code Blocks (The Org Manual))

コードブロックは次のような形式をしている。

#+NAME: <name>
#+HEADER: <header>...
#+HEADER: <header>...
#+BEGIN_SRC <language> <switch>... <header>...
<body>
#+END_SRC

#+BEGIN_SRC の後には言語名の他、様々なオプションを指定できる。また、 #+BEGIN_SRC の前で #+NAME で名前を付けたり、 #+HEADER で追加のオプションを指定したりできる。

インラインコードブロックは次のような形式をしている。

src_<language>{<body>}
src_<language>[<header>...]{<body>}

インラインコードブロックで指定できるオプションは通常のソースコードブロックとほぼ同等だが、結果の表現方法が違うため一部で使用できない機能がある(結果のキャッシュなど)。

より具体的な例は言語毎の書き方を参照のこと。

名前付きのコードブロック

コードブロックと結果の対応関係

コードブロックに名前を付けると結果との対応関係を明確に出来る。

コードブロックを評価した結果は通常コードブロックの直後に挿入されるが、コードブロックと同じ名前が付いた #+RESULTS: があればそこに挿入される。

#+NAME: elisp-hello-world-ex
#+BEGIN_SRC emacs-lisp
(concat "hello, " "world")
#+END_SRC

結果は次のようになる。

#+RESULTS: elisp-hello-world-ex
: hello, world

コードブロックと結果の間に何か文章を入れたい場合にはこのように名前を付けると良い。

C-c C-v r で指定した名前を持つ結果へジャンプすることも出来る。

名前の参照

コードブロックは他から名前で参照できる。

次の例ではEmacs Lispのコードブロックにmultiplyという名前を付けている。コードブロックには :var というヘッダー引数が二つ指定されている(xとyという変数を定義している)。

#+NAME: multiply
#+BEGIN_SRC emacs-lisp :var x=2 :var y=3
(* x y)
#+END_SRC

名前が付いたコードブロックは次のように他の場所から参照できる。

関数のように呼び出す例。エクスポートすると結果だけが出力される。

#+CALL: multiply(x=5, y=6)

#+RESULTS:
: 30

↑CALLの上でC-c C-cするとRESULTSが生成される。

noweb参照の例。 <<multiply>> と書いた部分が参照先のコードブロックの内容 (* x y) に置き換わる。 :noweb yes を指定すること。

#+BEGIN_SRC emacs-lisp :noweb yes
(defun multiply (x y)
  <<multiply>>
)
#+END_SRC

また、Emacs Lispのコードから org-babel-lob--src-info という関数を使ってコードブロックの情報を得ることも出来る。

#+begin_src emacs-lisp :results pp
(org-babel-lob--src-info "multiply")
#+end_src

#+RESULTS:
#+begin_example
("emacs-lisp" "(* x y)"
 ((:results . "replace")
  (:exports . "code")
  (:var . "x=2")
  (:var . "y=3")
  (:lexical . "no")
  (:tangle . "no")
  (:hlines . "no")
  (:noweb . "no")
  (:cache . "no")
  (:session . "none"))
 "" "multiply" 4211 "(ref:%s)")
#+end_example

CALLについてはコードブロックの呼び出し、noweb参照についてはnoweb参照を参照のこと。

C-c C-v g で指定した名前を持つコードブロックへジャンプすることも出来る。

ヘッダー引数

(公式マニュアル: Using Header Arguments (The Org Manual))

#+BEGIN_SRC <言語ID> の後には : で始まる様々なオプションが指定できる。

最も重要なのは :exports:results (最初のコロンと最後のsが抜けないように注意すること)の二つ。

なお、ヘッダー引数は C-c C-v C-j でインタラクティブに挿入できる。

:exports

:exports はエクスポート時の見た目(コードブロックがどうエクスポートされるか)を指定する。次のいずれかを指定できる。(公式マニュアル: Exporting Code Blocks)

  • コードブロックのみを出力する(code)
  • 実行結果のみを出力する(results)
  • 両方を出力する(both)
  • 何も出力しない(none)

:exports の例:

#+NAME none-exports-example
#+BEGIN_SRC emacs-lisp :exports none :var x=0
(* x x) ;;このコードはエクスポートされない。他から名前で参照されるためだけのもの。
#+END_SRC

:results

:results は実行結果をどのように扱うかを指定する(公式マニュアル: Results of Evaluation (The Org Manual))。大きく分けて四種類の値を組み合わせて指定できる。

  • Collection : どこから結果を得るか
    • value : 言語が返した値(デフォルト) (functional mode)
    • output : 標準出力 (scripting mode)
  • Type : 結果の種類(使用例は結果の受け取り方を参照のこと)
    • table : 表
    • list : リスト
    • scalar, verbatim : 単一の値
    • file : ファイルへのリンク
  • Format : 結果の出力形式
    • raw : そのままOrg文書として出力
    • org : orgのコードブロック(#+BEGIN_SRC org)として出力
    • html : htmlのエクスポートブロック(#+BEGIN_EXPORT html)として出力
    • latex : latexのエクスポートブロック(#+BEGIN_EXPORT latex)として出力
    • code : 同じ言語のエクスポートブロック(#+BEGIN_EXPORT 同じ言語)として出力
    • pp : pretty-printしたものを出力(一部の言語のみ対応)
    • drawer : :RESULTS::END: に挟まれた形で出力
  • Handling : 結果をどう文書中に挿入するか(#+RESULTS:として)
    • silent : 挿入しない
    • replace : 置き換える
    • append : 最後に付け加える
    • prepend : 最初に付け加える

:results の例:

#+BEGIN_SRC emacs-lisp :results value raw drawer
"Hello\n\n| table | table |\n| table | table |\n"
#+END_SRC

#+RESULTS:
:RESULTS:
Hello

| table | table |
| table | table |
:END:

:results は言語毎にデフォルト値が異なるので注意を要する。コードブロックの上で C-c C-v TAB を押すと現在の値が確認できる。または ob-<言語ID>.el の変数(org-babel-default-header-args:<言語ID>)や関数(org-babel-execute:<言語ID>)を見てどのように実装されているか確認する手もある。

エクスポート時の評価を抑制する(:eval)・結果のキャッシュ(:cache)

エクスポートするたびにコードブロックを評価するのは煩わしい場合がある。

そんな場合は :eval no-export を指定するとエクスポート時の評価を抑制できる。(公式マニュアル: Limit code block evaluation – Evaluating Code Blocks (The Org Manual))

または :cache yes を指定してあらかじめ実行しておくとエクスポートするたびにコードブロックを実行しなくて済む。ただしこの方法はインラインコードブロックには使用できない。(公式マニュアル: Cache results of evaluation – Evaluating Code Blocks (The Org Manual))

:var :session :dir :prologue :epilogue

:var
変数を定義
:session
セッション
:dir
カレントディレクトリ
:prologue
コードの先頭に挿入するコード
:epilogue
コードの最後に挿入するコード

詳しくは 公式マニュアル: Environment of a Code Block (The Org Manual) を参照のこと。

:noweb

noweb参照を参照のこと。

:tangle :mkdirp :comments :padline :shebang :tangle-mode :no-expand

コードブロックの内容を別のファイルに書き出す機能に関するオプション。

(公式マニュアル: Extracting Source Code (The Org Manual))

その他

コードブロック上で C-c C-v j を押すとヘッダー引数を選んで挿入できる。それでどんな物があるのかある程度確認できる。

noweb参照

(公式マニュアル: Noweb reference syntax – The Org Manual)

nowebとは文芸的プログラミング(Literate programming – Wikipedia)のツールなのだそうだ(noweb – Wikipedia)。

何はともあれ名前付きブロックを参照する書き方ができる。

まず名前付きのブロックを作る。次の例では js-hello-example という名前で suffix という変数も定義した。

#+NAME: js-hello-example
#+BEGIN_SRC js :var suffix="world"
return "hello_" + suffix;
#+END_SRC

それを << 名前 >> という形式で参照する。つまり <<js-hello-example>> とする。

#+BEGIN_SRC js :noweb yes
function sayHello(){
    <<js-hello-example>>
}
return sayHello();
#+END_SRC

これをエクスポートすると次のように中身がそのまま展開される。

#+BEGIN_SRC js :noweb yes
function sayHello(){
    return "hello_" + suffix;
}
sayHello();
#+END_SRC

括弧を付けると関数のように呼び出して実行結果に置き換わる。

#+BEGIN_SRC text :noweb yes
<<js-hello-example()>>
#+END_SRC

上は下のようにエクスポートされる。

hello_world

括弧の中に変数の値を指定するとコードに引き渡されて結果が変わる。

#+BEGIN_SRC text :noweb yes
<<js-hello-example(suffix="moon")>>
#+END_SRC

上は下のようにエクスポートされる。

hello_moon

公式マニュアル: Noweb Reference Syntax (The Org Manual)

言語毎の書き方

(公式マニュアル: Babel: Languages)

Emacs Lisp

Emacs LispはEmacsに組み込まれているため最も安定して使える。

Emacs LispのコードブロックはOrg文書中で次のように書ける。

Emacsのバージョンを表示するコードと結果は次の通り。

#+BEGIN_SRC emacs-lisp :exports both
(emacs-version)
#+END_SRC

#+RESULTS:
: GNU Emacs 25.3.50.1 (x86_64-w64-mingw32)
:  of 2017-09-20

#+BEGIN_SRC emacs-lisp#+END_SRC の間にカーソルを置いて C-c C-c を押すことで #+RESULTS: 以下が生成される。

ヘッダー引数 :exports には none code results both が指定でき、コード(リスティング)と結果をそれぞれエクスポートするかどうか指定できる。今回は both を指定しているためコードと結果の両方がエクスポートされる。実際にエクスポートすると次のようになる。

Emacsのバージョンを表示するコードと結果は次の通り。

(emacs-version)
GNU Emacs 25.3.50.1 (x86_64-w64-mingw32)
 of 2017-09-20

org-mode

Org文書の書き方を説明するためにOrg文書の中にorg言語のコードブロックを書くことは良くある(まさにこの文書)。

例えばOrg文書内での太字、表、コードブロックの書き方を例示したいときは次のように書く。

#+BEGIN_SRC org
太字の例:
*bold*

表の例:
|a|0|
|b|0|

コードブロック例:
,#+BEGIN_SRC emacs-lisp
(concat "hello" "world")
,#+END_SRC
#+END_SRC

これをエクスポートすると今上でご覧のようにorgのソースコードが表示される。

このソースコードを実際にエクスポートしたときの見た目を併記したい時はどうするか。

:exports result:exports both を指定してorgコードブロックの実行結果も一緒に出力させれば良い。 Org文書は本来プログラムではないので「orgコードブロックの実行」というのは何やら不思議な気もする。orgの実行方法は org-babel-execute:org 関数で定義されている。見てみると基本的にコードブロックの中身をそのまま返すだけとなっている。デフォルトは :results raw で返すので、結果はそのまま(生で)Org文書の中に埋め込まれる。

#+BEGIN_SRC org :exports both :results raw replace
太字の例:
*bold*

表の例:
|a|0|
|b|0|

コードブロック例:
,#+BEGIN_SRC emacs-lisp
(concat "hello" "world")
,#+END_SRC
#+END_SRC

これをエクスポートすると次のようにコードと結果が両方(both)表示される。

太字の例:
*bold*

表の例:
|a|0|
|b|0|

コードブロック例:
,#+BEGIN_SRC emacs-lisp
(concat "hello" "world")
,#+END_SRC

太字の例: bold

表の例:

a 0
b 0

コードブロック例:

(concat "hello" "world")

デフォルトの :results (変数 org-babel-default-header-args:org) が :results silent なため、そのままでは結果が出力されない。明示的に :results replace と指定する必要がある。 (注意: :replace を指定しても再実行時に #+RESULTS: の部分を置き換えてくれず、以前の結果の上に新しい結果を追加してしまう場合がある。結果がどこまでか判別するすべがない場合にこの現象が起きる。結果が単一要素の場合は正しく置き換えてくれる)

HTMLやJavaScriptのところで紹介するように #+CALL を使う方法もある。

#+NAME: org-example
#+BEGIN_SRC org :exports both :results raw replace
太字の例:
*bold*

表の例:
|a|0|
|b|0|

コードブロック例:
,#+BEGIN_SRC emacs-lisp
(concat "hello" "world")
,#+END_SRC
#+END_SRC

#+NAME: ref-org
#+BEGIN_SRC emacs-lisp :exports none :results raw :var ref=""
(cadr (org-babel-lob--src-info ref))
#+END_SRC

#+CALL: ref-org("org-example")

コードブロック内にコードブロックを書く方法

#+BEGIN_SRC#+END_SRC はネストできない。

#+BEGIN_SRC org
aaa
#+BEGIN_SRC org
bbb
#+END_SRC
ccc
#+END_SRC

これをエクスポートすると次のようになってしまう。

aaa
#+BEGIN_SRC org
bbb

ccc #+END_SRC

行頭の#(や*)をエスケープするには行頭に,を入れる。

#+BEGIN_SRC org
,#+BEGIN_SRC org
,*bold*
,#+END_SRC
#+END_SRC

上のように行頭にカンマを一つ表示させるために私は行頭にカンマを二つ打っている。

カンマを三つ打つと なぜかそのまま三つ表示される。 二つ表示される。

,,#+BEGIN_SRC org
*bold*
,,#+END_SRC

四つ打っても そのまま四つ表示される。 三つ表示される。

,,,#+BEGIN_SRC org
*bold*
,,,#+END_SRC

行頭に二つ表示させたい場合はどうしたら良いんだろう。 (いつの間にか修正された模様)

HTML

準備

  • 使っているモード(web-mode等)に合わせて org-src-lang-mode の書き換えが必要。

    (add-to-list 'org-src-lang-modes '("html" . web))
    

Org文書の中でHTMLのコードを例示しつつそのHTMLをエクスポートしたHTMLに埋め込む

HTMLの書き方の説明をOrg文書で書きたい場合、Org文書の中にHTMLのコードブロックを書くことになる。

例えば次のコードブロックは、HTMLでcanvas要素とscript要素を使って絵を書く例を示している。

#+BEGIN_SRC html :exports both
<div>
<canvas width="320" height="240" />
<script>
//<![CDATA[
  var canvases = document.getElementsByTagName("canvas");
  var canvas = canvases[canvases.length - 1]; //last canvas element
  var ctx = canvas.getContext("2d");
  var angle = 0;
  function draw(){
    ctx.fillStyle = "rgb(128, 128, 255)";
    ctx.fillRect(0, 0, 320, 240);

    ctx.fillStyle = "rgb(64, 64, 128)";
    ctx.beginPath();
    ctx.arc(160, 120, 110, 0, 2*Math.PI, false);
    ctx.fill();

    ctx.strokeStyle = "rgb(255, 255, 255)";
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(160, 120);
    ctx.lineTo(160+100*Math.sin(angle*Math.PI/180), 120-100*Math.cos(angle*Math.PI/180));
    ctx.stroke();
  }
  draw();
  setInterval(function(){ angle += 6; draw();}, 1000);
//]]>
</script>
</div>
#+END_SRC

当然「これをブラウザで見るとこうなりますよ」というようにHTMLの表示結果を併記したいのだが、素直にexportsにbothを指定しても結果はエクスポートされない。試しにC-c C-cでHTMLコードブロックを実行しようとすると失敗する。

org-babel-execute-src-block: No org-babel-execute function for html!

org-babel-execute:html が定義されていないのでそのままでは実行できない。

元々HTMLはプログラミング言語ではなくマークアップ言語なので、実行して結果が出るようなものではない。 しかしHTMLの解説をする場合に書き方とブラウザでの表示結果を併記したいことは良くあるし、そのために例として書いたマークアップをそのままエクスポートしたHTML文書に埋め込められれば便利だ。

解決方法は色々ある。

  1. noweb参照でコードの重複を避ける方法

    まず名前付きhtmlコードブロックを作成し、それを後からorgコードブロックから参照する。

    canvasを使う例:
    #+NAME: html-example
    #+BEGIN_SRC html :exports code
    <div>
    <canvas width="320" height="240" />
    <script>
    //<![CDATA[
      var canvases = document.getElementsByTagName("canvas");
      var canvas = canvases[canvases.length - 1]; //last canvas element
      var ctx = canvas.getContext("2d");
      var angle = 0;
      function draw(){
        ctx.fillStyle = "rgb(128, 128, 255)";
        ctx.fillRect(0, 0, 320, 240);
    
        ctx.fillStyle = "rgb(64, 64, 128)";
        ctx.beginPath();
        ctx.arc(160, 120, 110, 0, 2*Math.PI, false);
        ctx.fill();
    
        ctx.strokeStyle = "rgb(255, 255, 255)";
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(160, 120);
        ctx.lineTo(160+100*Math.sin(angle*Math.PI/180), 120-100*Math.cos(angle*Math.PI/180));
        ctx.stroke();
      }
      draw();
      setInterval(function(){ angle += 6; draw();}, 1000);
    //]]>
    </script>
    </div>
    #+END_SRC
    ………略………
    
    ………略………
    先のcanvasを使う例をブラウザで表示すると次のようになる:
    #+BEGIN_SRC org :noweb yes :exports results :results raw replace
    #+BEGIN_EXPORT html
    <<html-example>>
    #+END_EXPORT
    #+END_SRC
    

    これをHTMLでエクスポートすると、HTMLのリストの後にそのリストの中のHTML(<div>~</div>まで)がエクスポートされるHTML文書の中にそのまま挿入される。結果script要素が実行されてcanvas要素に描画が行われる。

    :results raw を使うのがミソ。rawはOrg形式としてそのまま文書に埋め込まれる。 :results org としてしまうと結果が #+BEGIN_SRC org#+END_SRC で囲われてしまうので注意。 #+BEGIN_EXPORT html :noweb yes と書ければ簡単なのだけど書けない。

  2. noweb参照とhereドキュメントで対処する方法

    1とほぼ同様だが、何かhereドキュメントが使える言語でコードブロックをそのままエクスポートする。 :results html は結果を #+BEGIN_EXPORT html で囲ってくれるので。

    #+BEGIN_SRC perl :noweb yes :results output html :exports results
    print<<EOF;
    <<html-example>>
    EOF
    #+END_SRC
    
  3. 実行関数を定義する方法

    org-babel-execute:html が定義されていないのが原因なので、素直に定義してしまえば良いという話。

       (defun org-babel-execute:html (body params) body)
    
    #+BEGIN_SRC html :results html :exports both :noweb yes
    <<html-example>>
    #+END_SRC
    
  4. #+CALL を使用する方法

    (参考: org mode – Export Javascript source block to script tag in HTML when exporting Org file to HTML – Emacs Stack Exchange)

    #+NAME: ref-html
    #+BEGIN_SRC emacs-lisp :exports none :results html :var ref=""
    (concat "<div>" (cadr (org-babel-lob--src-info ref)) "</div>")
    #+END_SRC
    
    #+CALL: ref-html("html-example")
    
  5. ob-browserを使用する方法

    ob-browser を使用するとPhantomJS経由でスクリーンショットを撮って画像化してくれる。

結果:


参考:

JavaScript

準備

  • node.jsをインストールしてnodeコマンドへパスを通す。
  • 変数 org-babel-js-cmd を設定(確認)する。
  • 別のモード(js2-mode等)を使っている場合は org-src-lang-mode の書き換えが必要。

    (add-to-list 'org-src-lang-modes '("js" . js2))
    
  • org-babel-load-languages に '(js . t) を追加

例1 コードとコンソールに出力した結果を併記する

#+BEGIN_SRC js :results output :exports both :cache yes
class Person{
    constructor(name, age){
        this.age = age;
        this.name = name;
    }
    greet(){
        return "my name is " + this.name + " " + this.age;
    }
}
var hanako = new Person("Kikuko", 17);
console.log(hanako.greet());
#+END_SRC

#+RESULTS:
: my name is Kikuko 17

コードブロック内のJavaScriptではconsole.logを使って結果を出力している。:resultsにoutputを指定することで標準出力に出力された文字列を結果として扱う。

例2 コードブロックに変数で値を引き渡し、コードが返した値を結果とする

#+BEGIN_SRC js :results value :exports both :cache yes :var count=3
return Array.from(Array(count).keys());
#+END_SRC

#+RESULTS:
| 0 | 1 | 2 |

ヘッダー引数 :var count=3 でJavaScriptへ値を引き渡している。JavaScriptのコードは配列 [0,1,2] をreturnで返している。 :results value で値を結果として扱う。結果はtableの形でOrg文書内に挿入される。

例3 コードを表示しつつエクスポートしたHTMLにも埋め込む例

コードブロック内のJavaScriptを、エクスポート後のHTML文書内に埋め込みたい場合もある。

最後の要素の親の親(最後のscript要素の親)へdiv要素を追加する例:

#+NAME: js-example
#+BEGIN_SRC js :exports code
(function(){
    var lastNode = document.body;
    while(lastNode.lastChild){ lastNode = lastNode.lastChild;}
    var div = document.createElement("div");
    div.innerHTML = "Hello World from JavaScript Code";
    div.style = "border: 1px solid;";
    lastNode.parentNode.parentNode.appendChild(div);
})();
#+END_SRC

実際にやってみる:

#+NAME: ref-js
#+BEGIN_SRC emacs-lisp :exports none :results html :var ref=""
(concat "<script>" (cadr (org-babel-lob--src-info ref)) "</script>")
#+END_SRC

#+CALL: ref-js("js-example")

↑ここに見える?

(参考: org mode – Export Javascript source block to script tag in HTML when exporting Org file to HTML – Emacs Stack Exchange)

Java

準備:

  • JDKをインストールする。
  • 変数を設定するかパスを通す。
    • org-babel-java-compiler (default: javac) (%JAVA_HOME%/bin/javac)
    • org-babel-java-command (default: java)
  • org-babel-load-languages に '(java . t) を追加

Javaのコードを実行するにはメインのクラス名を :classname で指定する必要がある。

#+BEGIN_SRC java :results output :exports both :classname HelloWorld :cmdline -Dorgmode.arg=test1234 :cache yes
public class HelloWorld {
    public static void main(String[] args){
        System.out.println("Hello");
        System.out.format("orgmode.arg=%s", System.getProperty("orgmode.arg"));
    }
}
#+END_SRC
Hello
orgmode.arg=test1234

変数(:var)や引数を渡す仕組みはない(Org9.1時点。org-babel-execute:javaを参照)。無理矢理やるならcmdlineとシステムプロパティを使うくらいか?

C/C++/D

準備:

  • 変数を設定する。
    • org-babel-C-compiler (default:gcc)
    • org-babel-C++-compiler (default:g++)
    • org-babel-D-compiler (default:rdmd)
  • org-babel-load-languages に '(C . t) を追加

例1:

#+HEADER: :includes <iostream> <cmath>
#+HEADER: :var x=1.0 :var y=2.0
#+BEGIN_SRC C++ :exports results :results output :cache yes
std::cout << "hello " << M_PI << std::endl;
std::cout << "x=" << x << " y=" << y << std::endl;
#+END_SRC
hello 3.14159
x=1 y=2

例2:

#+BEGIN_SRC C++ :exports results :results output table :cache yes
#include <iostream>

int main(int argc, char *argv[]){
    std::cout << 123 << " " << 456 << '\n'
              << 789 << " " << 012 << std::endl;
}
#+END_SRC
123 456
789 10

例3:

#+HEADER: :includes <iostream> <vector> <utility>
#+BEGIN_SRC C++ :exports both :cache yes
std::vector<std::pair<int, int>> v{{0,1}, {2,3}, {4,5}};
for(const auto &e : v){
    std::cout << e.first << ',' << e.second << '\n';
}
#+END_SRC
0 1
2 3
4 5

ditaa

準備:

  • ditaa.jarをどこかに配置する。(http://ditaa.sourceforge.net/#download)
  • 変数を設定する。
    • org-ditaa-jar-path
    • org-ditaa-jar-option
    • org-ditaa-eps-jar-path
  • org-babel-load-languages に '(ditaa . t) を追加
#+BEGIN_SRC ditaa :file ditaa-example.png :exports both :cache yes
+--------+   +-----------+   +-------------+
| Source +-->+ Processor +-->+ Destination |
+--------+   +-----------+   +-------------+
#+END_SRC
2017-10-26-ditaa-example.png

書き方等についてはditaaを参照のこと。

PlantUML

準備:

  • plantuml.jar をどこかに置いて org-plantuml-jar-path を設定すること。
  • plantumlの動作にはgraphvizのインストールと環境変数 GRAPHVIZ_DOT の設定が必要。
  • graphvizはCygwinのパッケージになっている。
  • org-babel-load-languages に '(plantuml . t) を追加

クラス図を描く例:

#+BEGIN_SRC plantuml :file plantuml-example.png :exports results :cache yes
World "1" *-right- "0..*" Animal : contains
Animal <|-- Dog
Animal <|-- Cat

World : void moveAllAnimals(double dt)
Animal : double age
Animal : double getAge()
Animal : void move(double dt)
Dog : void move(double dt)
Cat : void move(double dt)

note top of Animal
  Base class of all animals.
end note
#+END_SRC
2017-10-26-plantuml-example1.png

PlantUML自体については公式サイトを参照のこと。

dot

準備:

  • dotコマンドへパスを通しておく(一応:cmdヘッダーでも指定できるがおすすめはしない。ちなみに:cmdlineヘッダーも有効)
  • graphvizはCygwinのパッケージになっている。

適当な有向グラフを描く例:

#+BEGIN_SRC dot :file dot-example.png :exports results :cache yes
digraph {
  a -> b
  b -> c
  a -> c
}
#+END_SRC
2017-10-26-dot-example.png

dot自体の書き方については Graphviz | Graphviz – Graph Visualization Software を参照のこと。

R

準備:

  • インストールはインストーラで簡単
  • 変数 org-babel-R-command にRコマンドへのパスとコマンドライン引数を設定する
  • org-babel-load-languages に '(R . t) を追加

データを用意:

#+NAME: age-score-table
| Age | Score |
|-----+-------|
|  10 |    82 |
|  15 |   100 |
|   8 |    52 |
|  13 |    75 |
|  12 |    38 |
|   9 |    80 |
|  13 |    92 |
|  11 |    65 |
|  15 |    85 |
|  18 |    98 |
|   3 |    20 |
|  15 |    92 |
|  14 |    78 |
|  12 |    53 |
Age Score
10 82
15 100
8 52
13 75
12 38
9 80
13 92
11 65
15 85
18 98
3 20
15 92
14 78
12 53

org-modeの表から散布図を描く:

#+BEGIN_SRC R :var table=age-score-table :results output graphics :file r-plot.png :width 320 :height 320 :cache yes
plot(table)
abline(lm(table$Score ~ table$Age), col="red")
#+END_SRC
2017-10-26-r-plot.png

org-modeの表からヒストグラムを描く:

#+BEGIN_SRC R :var table=age-score-table :results output graphics :file r-hist.png :width 320 :height 320 :cache yes
hist(table$Age)
#+END_SRC
2017-10-26-r-hist.png

org-modeの表から年齢別スコアを集計(結果を表で表示する例):

#+BEGIN_SRC R :var table=age-score-table :results value :colnames yes :exports results
aggregate(x=list(Score=table$Score),by=list(Age=table$Age),FUN=function(x)c(Mean=mean(x), Count=length(x), Max=max(x), Min=min(x)))
#+END_SRC
Age Score.Mean Score.Count Score.Max Score.Min
3 20 1 20 20
8 52 1 52 52
9 80 1 80 80
10 82 1 82 82
11 65 1 65 65
12 45.5 2 53 38
13 83.5 2 92 75
14 78 1 78 78
15 92.3333333333333 3 100 85
18 98 1 98 98

:colnames yes:rownames yes を付けないと列名や行名を取りこぼす。

R Source Code Blocks in Org Modeに書いてあるようにasciiパッケージを使用してOrg形式で出力し、 :result output で受ける方法もある。

好きな関数をプロットする例:

#+BEGIN_SRC R :results output graphics :file r-function.png :width 320 :height 320 :cache yes
y <- function(x){return (sqrt(x))}
plot(y, 0, 1)
#+END_SRC
2017-10-26-r-function.png

R自体については R: The R Project for Statistical Computing を参照のこと。

結果の受け取り方

:results table

Emacs Lisp

#+BEGIN_SRC emacs-lisp :results table :exports results
'((1) (1 2) (3 4 5))
#+END_SRC
1    
1 2  
3 4 5

Java

#+BEGIN_SRC java :classname HelloWorld :results table :cache yes
class HelloWorld {
    public static void main(String[] args){
        final String[] hand = {"Guu", "Choki", "Paa"};
        System.out.println("\t" + hand[0] + "\t" + hand[1] + "\t" + hand[2]);
        for(int i = 0; i < 3; ++i){
            System.out.printf(hand[i]);
            for(int j = 0; j < 3; ++j){
                System.out.printf("\t%d", (4+j-i)%3-1);
            }
            System.out.printf("\n");
        }
    }
}
#+END_SRC
  Guu Choki Paa
Guu 0 1 -1
Choki -1 0 1
Paa 1 -1 0

:results list

#+BEGIN_SRC emacs-lisp :results list :exports results
'("orange" "apple" "banana")
#+END_SRC
  • orange
  • apple
  • banana

:results scalar

#+BEGIN_SRC emacs-lisp :results scalar :exports results
'("orange" "apple" "banana" ("tenpura" "sukiyaki"))
#+END_SRC
("orange" "apple" "banana" ("tenpura" "sukiyaki"))

:results pp

#+BEGIN_SRC emacs-lisp :results pp :exports results
'("orange" "apple" "banana" ("tenpura" "sukiyaki"))
#+END_SRC
("orange" "apple" "banana"
 ("tenypura" "sukiyaki"))

:results file

#+BEGIN_SRC emacs-lisp :results file :exports results :cache yes
(let ((filename "2017-10-26-file-result-example.txt"))
  (with-temp-buffer (insert "orange apple banana") (write-region (point-min) (point-max) filename))
  filename)
#+END_SRC

2017-10-26-file-result-example.txt

コードブロックの呼び出し

(公式マニュアル: Evaluating Code Blocks (The Org Manual))

まず名前付きのブロックを用意する。 次のコードは、標準出力へは”<b>hello world</b>”を出力し、値は123を返す。

#+NAME: call-ex1
#+BEGIN_SRC perl :var suffix=" world" :results value :cache yes :exports both
printf "<b>hello,$suffix</b>";
123
#+END_SRC
123

この名前付きブロックを呼び出す。

#+CALL: call-ex1[:results output](suffix=" moon") :results html

inline calling result: call_call-ex1[:results output](suffix=" moon")[:results html]

結果は次。

hello, moon

inline calling result: hello, moon

引数の前に指定するヘッダーは、呼び出し先ブロックに対して使われる。引数の後に指定するヘッダーは、得られた結果に対して使われる。

コードブロックから表を参照する方法

表に名前 #+NAME でを付けると :var 変数名 = 表名 で表の中身を参照できる。

#+NAME: payment-table
| 科目   | 金額 |
|--------+------|
| 交通費 |  320 |
| 食費   |  500 |
| 交通費 |  120 |
| 食費   |  140 |
| 交通費 |  300 |
| 食費   |  550 |

#+BEGIN_SRC emacs-lisp :var payments=payment-table :colnames yes
(let (alist)
  (cl-loop for line in payments do
           (let* ((class (nth 0 line))
                  (amount (nth 1 line))
                  (cell (or (assoc class alist)
                            (car (push (list class 0) alist)))))
             (setcar (cdr cell) (+ (cadr cell) amount))))
  alist)
#+END_SRC

#+RESULTS:
| 科目   | 金額 |
|--------+------|
| 食費   | 1190 |
| 交通費 |  740 |

Pingback / Trackback