Czy można mieć w tym samym pliku org dwa bloki kodu w tym samym języku, które działają w różnych interpretatorach, podając różne opcje na górze bloku kodu?
Czy można mieć w tym samym pliku org dwa bloki kodu w tym samym języku, które działają w różnych interpretatorach, podając różne opcje na górze bloku kodu?
Odpowiedzi:
Pierwotne pytanie zostało zmodyfikowane, aby dotyczyło uruchamiania wielu wersji pliku wykonywalnego, a nie tylko niezależnych tłumaczy.
Za pomocą find-library
sprawdziłem źródło ob-ruby
, które zawiera ten kod:
(defvar org-babel-ruby-command "ruby"
"Name of command to use for executing ruby code.")
Widziałem odniesienia gdzie indziej dotyczące używania Pythona org-babel-python-command
, więc istnieje on w innych językach, sprawdź odpowiednie ob-$lang
wsparcie, aby zobaczyć.
Umożliwia to działanie następujących elementów:
#+begin_src emacs-lisp :results none
(setq org-babel-python-command "python3")
#+end_src
#+begin_src python :results output
import sys
print(sys.version)
#+end_src
#+RESULTS:
: 3.4.0 (default, Apr 11 2014, 13:05:11)
: [GCC 4.8.2]
#+begin_src emacs-lisp :results none
(setq org-babel-python-command "python2")
#+end_src
#+begin_src python :results output
import sys
print(sys.version)
#+end_src
#+RESULTS:
: 2.7.6 (default, Mar 22 2014, 22:59:56)
: [GCC 4.8.2]
Można to połączyć z :session python3
i, :session python2
aby uniknąć wywołania elisp przed każdym blokiem. Wydaje się jednak, że powinien istnieć prostszy sposób na zrobienie tego.
org-babel-post-tangle-hook
. Ktoś powinien wdrożyć o org-babel-pre-tangle-hook
.
:interpreter
nieruchomości.
:interpreter
ma sens. Ale org-babel-post-tangle-hook
działa po wykonaniu C-c C-c
kodu w bloku kodu. Zakładam pre
, że działałby przed wykonaniem kodu. Ale teraz zdaję sobie sprawę, że zmiana globalnej zmiennej miałaby złe skutki uboczne. :interpreter
byłoby lepiej.
:interpreter
opcję do org-babel-execute:js
. Ale po przejrzeniu źródła org-babel-execute:js
odkryłem, że istnieje już :cmd
opcja, która robi dokładnie to, co chcę. Niestety, :cmd
nie jest dostępny we wszystkich językach, a także nie znalazłem żadnej dokumentacji, ob-js
więc początkowo brakowało mi :cmd
istnienia.
:cmd
, ale wyglądało to tak, jakby służyło tylko do dołączania argumentów do polecenia interpretera. Czy mógłbyś odpowiedzieć na swoje pytanie z pełnym przykładem pokazującym zastosowanie :cmd
rozwiązania problemu dla tych, którzy mają ten problem w przyszłości?
Wierzę, że domyślnie każdy blok działa w niezależnym tłumaczu, nawet jeśli jest to ten sam język. W niektórych językach zachowanie może być inne. Na przykład nie jestem pewien, czy bloki emacs-lisp obsługują właściwość sesji.
#+BEGIN_SRC ruby
a = "foo"
#+END_SRC
#+RESULTS:
: foo
#+BEGIN_SRC ruby
a ||= "bar"
#+END_SRC
#+RESULTS:
: bar
#+BEGIN_SRC ruby :session foo
a ||= "session foo"
#+END_SRC
#+RESULTS:
: session foo
#+BEGIN_SRC ruby :session foo
a += " with bar"
#+END_SRC
#+RESULTS:
: session foo with bar
Pierwsze dwa bloki używają niezależnych tłumaczy, ale trzeci i czwarty blok współużytkują sesję :foo
, aby oceniać w tym samym tłumaczu.
Okazuje się, że w prawie wszystkich językach obsługiwanych przez Org Babel nie ma opcji użycia innego interpretera dla określonego bloku kodu. Jednym godnym uwagi wyjątkiem (i tym, który mnie interesuje) jest JavaScript. W takim przypadku można skorzystać z :cmd
opcji.
Standardowy interpreter JS jest node
zdefiniowany w zmiennej org-babel-js-cmd
. Aby uruchomić określony blok kodu przez innego interpretera, przepuść :cmd
opcję jak w poniższym przykładzie.
#+begin_src js :cmd "/usr/bin/osascript -l JavaScript"
app = Application.currentApplication()
app.includeStandardAdditions = true
app.say("Hello")
#+end_src