If each block in the file uses its own language and/or its own tangle path, then you will have to examine each one separately. That's what I assumed at first and that assumption is behind my original comment: you would have to loop over all of the blocks and treat each one separately.
But after you added clarifications in the comments (which should really be in the question itself), the following answer assumes that every source block in the Org mode file uses the same language and the same :tangle path spec, so that all the tangled blocks end up in the exact same file. There is then no need to examine each source block for those values: they will all have the same values, so getting the values from one of them should be enough.
Proceeding on that assumption, we end up with something like this:
(defun my/get-lang-and-path () "Get lang and path info from the first source block in the file" (save-excursion (goto-char (point-min)) (org-babel-next-src-block) (let* ((info (org-babel-get-src-block-info)) (lang (car info)) (path (cdr (assq :tangle (caddr info))))) (if (null info) nil (list lang path))))) (defun mda/tangle-tex-compile-open-pdf() "Generate and open a PDF from an org file containing tex blocks." (interactive) (let* ((info (my/get-lang-and-path)) (lang (car info)) (path (cadr info)) (directory (file-name-directory path)) (filename (file-name-nondirectory path)) (basename (file-name-base path))) ;; tangle all the code blocks (org-babel-tangle) (let ((default-directory (expand-file-name (or directory ".")))) ;; generate PDF file - appropriate command depends on language (cond ((string= lang "latex") (shell-command (concat "xelatex -interaction=nonstopmode " filename))) ((string= lang "lilypond") (shell-command (concat "lilypond " filename))) (t (message "Unknown language"))) ;; ...and show it if it exists (if (file-exists-p (concat basename ".pdf")) (shell-command (concat "evince " basename ".pdf")) (message "%s.pdf does not exist in directory %s" basename default-directory)))))
There is no error checking, but the code does not barf with or without code blocks. I tested with
emacs -q -l foo.el foo.org
where foo.el includes the two functions shown above and foo.org looks like this:
#+PROPERTY: header-args :comments org :tangle tangle/foo.tex * Test #+name: doc-preamble #+begin_src latex \documentclass{article} \begin{document} #+end_src #+name:doc-body #+begin_src latex \int_0^\infty 1 dx = \infty #+end_src #+begin_src latex \end{document} #+end_src
or like this:
#+PROPERTY: header-args :comments org :tangle tangle/foo.tex * Test No code blocks here.
I get reasonable behavior in either case, although the error handling in the second case is insufficient for "production" use.
org-babel-get-src-block-infoto get at the header args.org-babel-get-src-block-infois very useful indeed. However, I can't find how to make it work when called from a function evaluated outside of the tangled buffer (see my edit for more details).