org bable use tangle and export to a specified file - emacs

I tried to export the src code in org babel src to a file
#+name: src_file
#+BEGIN_SRC shell :results none :tangle ~/test-tangle :exports both
echo "very strang and long string"
#+END_SRC
Test it
#+BEGIN_SRC shell :results output
cat ~/test-tangle.sh
#+END_SRC
but get error
cat: ~/test-tangle.sh: No such file or directory
Then changed tangle to yes
#+name: src_file_2
#+BEGIN_SRC shell :results noe :tangle yes :exports both
echo "very strang and long string"
#+END_SRC
After C-c C-c, search the home dir for "very strange and long string", but just get the current org file.
Where is the src code export to?

You need to tangle the file with C-c C-v t (M-x org-babel-tangle). By the way, be aware that tangle will overwrite your existing file (with the same name) without warning.

Related

How can I have global :var binding for org-mode code block header?

With emacs/org-mode, I can define variable binding per code block, as demonstrated below.
#+HEADER: :var release="release-0.5"
#+begin_src shell :results output verbatim
echo $release
#+end_src
#+RESULTS:
: release-0.5
#+HEADER: :var release="release-0.5"
#+begin_src shell
echo "Indeed the release is $release"
#+end_src
#+RESULTS:
: Indeed the release is release-0.5
However, I wonder if there is a way to avoid the duplication, to define the variable binding globally, or per section?
I tried the following, it does not work:
* Release Package the script to be portable
:PROPERTIES:
:header-args:var: release="release-0.5"
:END
#+begin_src shell :results output verbatim
echo $release
#+end_src
#+RESULTS:
:
#+begin_src shell
echo "Indeed the release is $release"
#+end_src
#+RESULTS:
: Indeed the release is
EDIT: (adopting #Enze Chi's suggestion)
The following still doesn't work:
:PROPERTIES:
:header-args:shell:var release="release-0.5"
:END
#+begin_src shell :results output verbatim
echo $release
#+end_src
#+RESULTS:
:
#+begin_src shell
echo "Indeed the release is $release"
#+end_src
#+RESULTS:
: Indeed the release is
I wonder if there is a way to make it work?
The name of the propery is header-args:shell; the value of the property is :var release="release-0.5". The syntax of a properties drawer is:
:PROPERTIES:
:NAME: VALUE
:END:
so in this case:
:PROPERTIES:
:header-args:shell: :var release="release-0.5"
:END:
Note that the name of the property has to be wrapped in colons (:) and there has to be a space after the ending colon to separate the name part from the value part, because that's how property names are syntactically recognized.
So the colon before and after the name of the property (header-args:shell) is part of the property syntax, the colon in header-args:shell is part of the name itself, and the colon in :var release="release-0.5" is part of the value itself; and you need a space between the "colonized" name and the value. You got to keep your colons straight!
See Property Syntax and Using header arguments in the Org mode manual for all the details.
Should be the language after headers-arg
:header-args:shell: :var release="release-0.5"

Last source block can't be recognized

I have these three code blocks, but when i C-c C-c the last one, emacs tells me
C-c C-c can't do anything useful here
#+BEGIN_SRC org
,#+BEGIN_SRC python
print('hello');
,#+END_SRC
,#+RESULTS:
: None
#+END_SRC
#+BEGIN_SRC org
,#+BEGIN_SRC python :results output
print('hello');
,#+END_SRC
,#+RESULTS:
: hello
#+END_SRC
#+BEGIN_SRC python
return 1-2+100
#END_SRC
This is code blocks inside code blocks. Am I doing anything wrong that I can't see, or is this some sort of bug?
An even more dense example is this, that gives me the same
#+BEGIN_SRC org
,#+BEGIN_SRC python
,#+END_SRC
#+END_SRC
#+BEGIN_SRC org
,#+BEGIN_SRC python
,#+END_SRC
#+END_SRC
#+BEGIN_SRC python
return 1-2+100
#END_SRC
You are missing a + sign in the last line, which should read #+END_SRC, not #END_SRC.

Emacs org-babel with ob-julia.el does not work anymore with Julia V1.0

I am using ob-julia.el to create my Julia notebooks under Emacs. However with the new Julia v1.0 release it does not work anymore.
For instance a basic org-mode document like this one:
#+BEGIN_SRC julia :exports both :session mySession
1+2
#+END_SRC
returns now an empty #+RESULT
If I look at mySession buffer I see this error message
julia> ERROR: UndefVarError: writecsv not defined
Stacktrace:
[1] top-level scope at none:0
The reason is that the Emacs package ob-julia.el has not been upgraded to support the lastest v1.0 Julia release.
In this v1.0 version, the readcsv and writecsv functions do not exist anymore. They have been remplaced by the DelimitedFiles.readdlm and DelimitedFiles.writedlm functions.
However ob-julia.el still uses them:
(defvar org-babel-julia-write-object-command "writecsv(\"%s\",%s)")
and
(format "%s = readcsv(\"%s\")" name file)
(format "%s = readcsv(\"%s\")"
name file))))
I have submitted an ob-julia.el issue. However there is a possible quick and dirty fix if you want to still use ob-julia.el right now. Simply add these lines in your ~/.julia/config/startup.jl file:
import DelimitedFiles
function writecsv(filename::AbstractString,ans)
DelimitedFiles.writedlm(filename,ans,',')
end
function readcsv(filename::AbstractString)
DelimitedFiles.readdlm(filename,',')
end
This will redefine the readcsv and writecsv functions and make ob-julia.el work again.
With this fix, I get now:
#+BEGIN_SRC julia
1+2
#+END_SRC
#+RESULTS:
: 3
#+BEGIN_SRC julia :session mySession
1+2
#+END_SRC
#+RESULTS:
: 3
as expected.
This breaks building several Julia packages for me. As a workaround-workaround, I moved Picaud's code to ~/.julia/config/startup-babel.jl.
UPDATE:
That customization no longer seems to work. This one works for me. Do M-x customize-apropos and search for julia. Find Org Babel Julia Command and set it to (you may want your own path to Julia in there, of course):
julia -e 'include("$(ENV["HOME"])/.julia/config/startup-babel.jl")' -i
OLD CUSTOMIZATION THAT NO LONGER WORKS FOR ME:
Then I customized Ess Julia's Inferior Julia Args variable to
-e include("$(ENV["HOME"])/.julia/config/startup-babel.jl") -i

Emacs org-mode - How to run shell scripts with backgrounded processes without hanging Emacs

Add this to an emacs .org file:
#+BEGIN_SRC sh :results verbatim
#!/bin/bash
exec 2>&1 # <-- Because Emacs treats stderr output as an error and doesn't show it in the RESULT
echo before
# This nohup should just run in the background and continue to exit
# the script, but emacs hangs and waits on it anyhow:
nohup sleep 10 &
# Failed attempts at working around the hang are:
# setsid nohup sleep 10 &
# nohup sleep 10 </dev/null &
# Do see /tmp/ps.out being updated here so the hang is in Emacs:
ps -ef --forest --cols=10000 >/tmp/ps.out
echo after
exit 0
#+END_SRC
Move the point (cursor) into the BEGIN_SRC block and evaluate it using C-c C-c (which is bound to org-ctrl-c-ctrl-c).
Watch what happens. Emacs sits there and hangs. What I want it to do is run that command (sleep 10 in this trivial example) and continue on.
Somehow Emacs is trying to wait on all subprocesses that the script creates and hangs there. I have to hit C-g to get control back.
The use case for this is that I want to invoke some GUI application (xterm, etc.) and have it run in the background but give control immediately back to Emacs.
How can I do that? See my failed attempts above.
EDIT: I isolated the issue to the bare minimum Emacs Lisp code. Evaluate the following inside your *scratch* (Lisp Interactive) buffer and see that it hangs for the 3 seconds:
(let ((shell-file-name "/bin/bash")
(input-file "/tmp/tmpscript.sh")
(error-file "/tmp/tmperror")
(shell-command-switch "-c")
(command "sh")
exit-status)
(with-temp-file input-file
(insert "#!/bin/bash") (newline)
(insert "nohup sleep 3 &") (newline)
(insert "exit 0") (newline))
(setq exit-status
(apply 'call-process "/bin/bash"
input-file
(list t error-file)
nil
(list "-c" "sh"))))
Change the sleep 3 to something like sleep 3000 and it will hang for 3000 seconds until you kill it with C-g.
My emacs version reports:
GNU Emacs 24.4.50.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.4.2) of 2014-09-14 on hungover
I use ob-async from MELPA to enable asynchronous executions.
.emacs:
(require 'ob-async)
.org:
#+BEGIN_SRC sh :async
sleep 10 && echo 'Done!'
#+END_SRC
Here is the closest I can think of using https://github.com/jwiegley/emacs-async
* Run shell command asynchronously
#+BEGIN_SRC sh :tangle some_cmd.sh :tangle-mode (identity #o755) :shebang #!/bin/bash
sleep 10
touch async-file
echo "done"
#+END_SRC
#+RESULTS:
#+BEGIN_SRC emacs-lisp
(require 'async)
(org-babel-tangle)
(async-start
(lambda ()
(shell-command (expand-file-name "some_cmd.sh")))
(lambda (result)
(message-box "%s" result)))
#+END_SRC
#+RESULTS:
: #<process emacs>
#+BEGIN_SRC sh
ls async-file
#+END_SRC
or for your particular use:
(require 'async)
(async-start
(lambda ()
(shell-command "xterm"))
(lambda (result)
(message-box "%s" result)))
I am using emacs lisp start-process:
For example, to open libreoffice calc sheet
#+BEGIN_SRC elisp :noweb yes :results output :eval no-export :exports none
(start-process "server" "buf-server" "libreoffice" "calc.ods")
#+END_SRC
or to launch a java server (in the example tabula) in the background in xterm
#+BEGIN_SRC elisp :noweb yes :results output :eval no-export :exports none
(start-process "server" "buf-server" "xterm" "-T" "TABULA" "-hold" "-e" "bash" "-c" "java -Dfile.encoding=utf-8 -Xms256M -Xmx1024M -jar ~/java/tabula.jar")
#+END_SRC
I use links. I added & to the command for an sh link. With & the process starts in the background:
[[shell:afplay '/path/to/20200523-20123124.m4a' &][sample link]]
I added (setq org-confirm-shell-link-function nil) b/c I have hundreds of small m4a files to transcribe ... this isn't safe to set but for now it's ok.
Running the link (with C-x C-o) opens a new org shell output window, but I just ignore it.
Cheers! z

FIXED: emacs:org-babel: noweb reference expand with an surplus line

When noweb reference in org-mode 's source code block is expanded, ever the content of the reference consists of only one line, it will expand the reference with an surplus line. This is an example:
The source block is :
#+srcname: test
#+begin_src sh
hello
#+end_src
#+begin_src sh :tangle ~/tmp/1.sh
echo "<<test>>, world!"
#+end_src
and the block's expand result is:
echo "hello
echo ", world!"
How can I modify OR setup, so that I can get the expand result like this:
echo "hello, world!"
Answer: see the comment.
Which version of org-mode are you using?
I'm not sure why you are getting the newline added, but your example, as given, does not work because you are missing the :noweb yes header argument. I have this code:
testing
#+srcname: test
#+begin_src sh
hello
#+end_src
#+begin_src sh :tangle ~/tmp/1.sh :noweb yes
echo "<<test>>, world!"
#+end_src
When I run org-babel-tangle (bound to C-c C-v C-t), I get this:
tmp$ cat 1.sh
echo "hello, world!"
I'm using org-mode version: 7.7 (release_7.7.303.g56de2c.dirty)