Org-mode Babels :file with link abbreviations - emacs

I have some link-abbreviations in org-mode like this:
(setq org-link-abbrev-alist
'(("dropboxpath" . "~/Dropbox")
("cloudpath" . "~/")
("imgpath" . "~/images")
("gitpath" . "~/git")
))
It works fine and as i am working on different systems and syncing my org-files the paths are different on every system. My problem is the following:
#+BEGIN_SRC plantuml :file gitpath:/test.png
<some plantumlstuff here>
#+END_SRC
This is not working, org-babel does not recognize the link abbreviation.
I also tried the following (where temp is a variable containing the path to the git-directory):
#+BEGIN_SRC plantuml :file (concat temp "/test.png")
This works in principle but gives me the following result:
#+RESULTS:
[[file:~/git/test.png]]
This does not meet my requirements though because i need gitpath in order to make it work over all my machines...
#+RESULTS:
[[gitpath:/test.png]]
Does anybody have a suitable solution to this problem?

You can simply refer to org-link-abbrev-alist. Since that variable is structured as an alist, you can use assoc. It returns the first element of the alist that matches the supplied key.
(concat
(car (assoc "gitpath" org-link-abbrev-alist))
"/test.png")

Related

Open Pelican relative path in emacs org-mode

I'm using Pelican, a static site generator, to provide an html personal wiki or knowledge base using .org files as its base. Links to internal content in Pelican use the syntax {filename}/path/to/file. However, since I'm using emacs org-mode, I would also like to be able to follow such links to their relevant files in org-mode. I'm hoping that there is a simple function I could write which would allow org-mode to follow such a link and open the relevant file, without compromising Pelican's use of the internal link syntax. I suspect that this might be done by means of org-add-link-type and a function which parses the proper absolute path to the file. But my elisp-fu is weak, and I'm unsure of how to proceed. Help appreciated!
Edit: just to give an example, I might have a link like [[file:{filename}/path/to/file.org]] in an org file. Is there a way to get org to open the file by substituting (maybe via regexp?) an absolute file path for {filename}, but also wouldn't alter the original link so that Pelican can still process it correctly?
I think you want something like:
#+BEGIN_SRC emacs-lisp
(org-add-link-type
"pelican"
(lambda (path) (org-open-file path))
;; ; export
(lambda (path desc backend)
(cond
((eq backend 'html)
(format "{filename}/%s" (file-relative-name path))))))
#+END_SRC
Link to internal content pelican:/Users/jkitchin/blogofile-jkitchin.github.com/_blog/blog.org
#+BEGIN_SRC sh
pwd
#+END_SRC
#+RESULTS:
: /Users/jkitchin/blogofile-jkitchin.github.com/_blog
exports to:
<p>
Link to internal content {filename}/blog.org
</p>
Using the original answer by John Kitchen as a basis to build upon (along with this answer), the best function I came up with is the following:
(org-add-link-type
"pelican"
(lambda (path) (org-open-file path))
;; ; export
(lambda (path desc backend)
(cond
((eq backend 'org)
(format "[[file:{filename}/%s][%s]]" path (or desc "")))
((eq backend 'html)
(format "%s" path (or desc "")))
((eq backend 'md)
(format "[{filename}/%s](%s)" path (or desc ""))))))
Depending on the backend used for org-publish the function will provide relative links for org, html, or markdown.

How to add more items to a list in Elisp

I don't know any ELisp, but I need to configure the list of languages to use evaluate source code blocks inline using Org-Babel.
Using this site, I was able to get Python source-code blocks executed. However, I would now like to add support for other languages like C, C++, Matlab and others.
I know I must add identifiers as mentioned on this site to the variable org-babel-load-languages. How do I add the extra elements to
this list?
Currently I am setting the variable org-babel-load-languages via,
this code in my .spacemacs file
(org-babel-do-load-languages
'org-babel-load-languages
'((python . t)))
The enabled languages is a list (...) where each list item looks something like (python . t)
So you could extend your current code like so:
(org-babel-do-load-languages
'org-babel-load-languages
'((python . t)
(c . t)
(cpp . t)
(matlab . t)))
I'm using something like this to generate the same result:
(eval-after-load "org"
'(org-babel-do-load-languages
'org-babel-load-languages
(mapcar (lambda (lang) (cons lang t))
'(python c cpp matlab))))

org-mode doesn't like c++-mode

I'm using org-mode (Emacs: 24.3.1, org-mode: 7.9.3f 8.0.6) for a database of code snippets in different languages (so far mainly elisp and python). This works very nice using org-mode-babel, i.e. after creating a "code field" as explained in the documentation I can edit the code using the correct major-mode by issueing C-c ' (i.e. org-edit-special). However, when editing C++ source snippets such as
#+begin_src c++
std::vector<int> v( 100 );
std::iota( std::begin( v ), std::end( v ), 0 ); // Fill with 0, 1, ..., 99.
#+end_src
The error message
byte-code: Language mode `c++-mode' fails with: "Buffer *Org Src snippets.org[ c++ ]* has no process"
is prined (snippets.org is the name of the file I use to store the snippets). Furthermore, I can not save any changes made in the temporary buffer (which actually opens) and can not exit the temporary buffer using C-c '.
Anyone encountered this problem previously?
UPDATE: I found the culprit! The auto completion source ac-source-clang-async is responsible for screwing it up. My ac-clang config:
(defun ac-cc-mode-clang-setup ()
(message " * calling ac-cc-mode-clang-setup")
(setq ac-clang-complete-executable "~/.emacs.d/site-lisp/emacs-clang-complete-async/clang-complete")
(setq ac-clang-cflags
(mapcar (lambda (item)(concat "-I" item))
(split-string
"
/usr/include/c++/4.7
/usr/include/c++/4.7/x86_64-linux-gnu
/usr/include/c++/4.7/backward
/usr/lib/gcc/x86_64-linux-gnu/4.7/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
/usr/local/root_v5.32.04/include
"
)))
(setq ac-clang-flags ac-clang-cflags)
;; (setq ac-sources (append '(ac-source-clang-async ac-source-yasnippet) ac-sources))
(setq ac-sources '(ac-source-filename ac-source-clang-async ac-source-yasnippet))
(ac-clang-launch-completion-process)
(ac-clang-update-cmdlineargs))
(defun ac-cc-mode-clang-config ()
(message " * calling ac-cc-mode-clang-config")
(add-hook 'c-mode-common-hook 'ac-cc-mode-clang-setup)
(add-hook 'auto-complete-mode-hook 'ac-common-setup))
(ac-cc-mode-clang-config)
Upon commenting this out, everything works nicely. I assume that the problem occurs because ac-clang wants to execute clang on the source file, which does not exists because its a purely virtual buffer (meaning: there is no associated file). However, I don't want to lose support for using ac-clang when writing programs... I think this might be solved if ac-cc-mode-clang-config is only executed when I'm doing genuine C++ edits (not org-mode c++ edits). Any ideas how to solve this?
This works for me:
#+begin_src C++ :includes '(<vector> <numeric> <iostream>) :flags -std=c++11
std::vector<int> v( 100 );
std::iota( std::begin( v ), std::end( v ), 0 );
std::cout << v[7];
#+end_src
#+RESULTS:
: 7
Emacs 24.3.4. Org 8.0.6.
org-setup
(org-babel-do-load-languages
'org-babel-load-languages
'( (perl . t)
(ruby . t)
(sh . t)
(python . t)
(emacs-lisp . t)
(matlab . t)
(C . t)))
Try with "C++" (capital C) or "cpp". Also try using a very recent version (one week or so). I think Eric Schulte has patched something for this.
Solved it! This has actually already been a bug in ac-clang-async, where it was fixed some time ago. However, the problem persists if you have a function configuring ac-clang-async which is executed whenever c-mode-common-hook (or a similar hook) is executed. The configuration process then breaks org.
If you want the configuring process to be executed whenever a file is opened (i.e. if the include paths depend on some file/buffer-local variable), you should wrap your configuration in the following snippet:
(defun my-ac-clang-config()
(let ((filename (buffer-file-name)))
(if filename
; Your config stuff
)
)
)

How to concat a pattern in Emacs Lisp?

I think the title can't describe the question clearly. But I will try to describe in more detail words.
Here is my Emacs lisp code to set the backup folder:
(setq backup-directory-alist '(("" . "/hom/test/.backups")))
But if I want to do this job by generating the backup path in a dynamic way, which generates the path based on the user's path.
Here is what I am trying to do:
(setq temp-file-folder "/home/test")
(setq backups-save-folder (concat temp-file-folder "/.backups"))
(setq backup-directory-alist '(("" . backups-save-folder)))
But it doesn't work. The final output of above code is:
(("" . backups-save-folder))
I think what I am trying to get should be:
(("" . "/home/test/.backups"))
So, what's the right code to generate the path dynamic? What's the meaning of . in the code?
Thanks
First, a point. You can use the format function instead of concat to do this (it's similar to printf). Here is an example
(let ((home_dir "/home/noufal")
(posts_dir "posts"))
(format "%s/%s" home_dir posts_dir))
evaluates to "/home/noufal/posts"
It's not idiomatic lisp to setq temporary variables. You should work within the scope of a let construct which can bind values to a few temporary symbols and then get your work done.
In your last case, you've used a ' before your second parameter. This will prevent it from being evaluated (it's synonymous to "quote literally") and so, the backups-save-folder will not be replaced with the value. If you want do that, do something like this.
(setq backup-directory-alist (list (cons "" backups-save-folder)))
The . is a way of representing lists whose cdr is not a list. Refer the elisp documentation for more details.
seems you don't need an associated list, designed to store paired values, but a simple list:
get the current user directory (getenv "HOME")
maybe combined with another arbitrary string "-BACKSTAGE-AREA"
(setq my-dir (list (concat (getenv "HOME")"-BACKSTAGE-AREA")))
get the directory name stored that way with
(car my-dir)
According to Noufal Ibrahim's answer, here is my final code:
(setq backup-directory-alist (list (cons ""
(let ((backups_dir "/.backups")
(temp_folder desktop-temp-file-folder))
(format "%s/%s" temp_folder backups_dir)))))
It works.
Thanks

Org-mode fails to export when passing arguments to code blocks that exports results

When passing arguments to code block that exports results Org-mode fails to export with the error "Wrong type argument: listp". How can I fix this?
Here is an example. When it is exported it gives the error 'Wrong type argument: listp, "bar"'.
#+TITLE: Example
#+SOURCE: example-one
#+BEGIN_SRC emacs-lisp :exports results
(setq foo "bar")
#+END_SRC
#+SOURCE: example-two
#+BEGIN_SRC emacs-lisp :exports results :var x=example-one
(setq foo (concat x x))
#+END_SRC
I am running Org-mode 7.6 in Emacs 23.3.1.
This issue might simply be with the older copy of Org that you're running. Tested it today with a recent git pull and get the results below. As pmr suggested, you might have better luck asking on the mailing list ( emacs-orgmode#gnu.org ) since there might be someone there who would know what caused this issue and what might have been changed to resolve it in later versions.
The features and examples discussed in the manual are based on the current release version (7.8.03 in this case) so they will not always be compatible with older versions. Does the info-node in your version indicate that it should work?
These 2 commands will show you the associated info-nodes for that section of the Org Manual
; The node itself
(Info-goto-node "(org) var")
; Parent node, in case the first node isn't present
(Info-goto-node "(org) Working With Source Code")
Test Results
Org
* Test variable passing
Headlines are created to split the code blocks apart. When trying to eval on export I'm getting a syntax read error which was reported here: http://lists.gnu.org/archive/html/emacs-orgmode/2012-01/msg00993.html
** Ex 1
#+name: example-one
#+BEGIN_SRC emacs-lisp :exports results
(setq foo "bar")
#+END_SRC
** Ex 2
#+name: example-two
#+BEGIN_SRC emacs-lisp :exports results :var x=example-one
(setq foo (concat x x))
#+END_SRC
Latex
\vspace*{1cm}
Headlines are created to split the code blocks apart. When trying to eval on export I'm getting a syntax read error which was reported here: \href{http://lists.gnu.org/archive/html/emacs-orgmode/2012-01/msg00993.html}{http://lists.gnu.org/archive/html/emacs-orgmode/2012-01/msg00993.html}
\section{Ex 1}
\label{sec-1}
\begin{verbatim}
bar
\end{verbatim}
\section{Ex 2}
\label{sec-2}
\begin{verbatim}
barbar
\end{verbatim}
in your .emacs file - make sure you have the following line:
(setq org-babel-load-languages
(quote ((emacs-lisp . t))))