Customizing org-mode exports - emacs

So, I have been using org-mode for taking my research notes for some time now. I love how I can seamlessly export to both latex (for my papers) and html (for my blog). However, whenever I define macros with \newcommand with #+LATEX_HEADER, these do not show up in the HTML export at all.
I currently handle this by putting the all these commands as
(\newcommand \newcommand etc. etc.)
at the top and then manually removing the "(" and ")" from the tex file.
What I wish I could do was to keep a drawer for these commands and customize html and latex export of org mode to handle this drawer appropriately.
For example, I would add the following in the org file:
:LATEX_MACROS:
\newcommand{\norm}[1]{\lVert{#1}\rVert}
\newcommand{\abs}[1]{\lvert{#1}\rvert}
\newcommand{\half}{\frac{1}{2}}
:END:
And after export, this shows up in the latex file verbatim in header section
and in the html file as
\(
\newcommand{\norm}[1]{\lVert{#1}\rVert}
\newcommand{\abs}[1]{\lvert{#1}\rvert}
\newcommand{\half}{\frac{1}{2}}
\)

Here's a standalone way that works with Org, pdflatex and MathJax at the time of this writing. Make sure the drawers (or at least the LATEXMACROS drawer) are exported (this is the default), then insert near the top of the Org file:
#+OPTIONS: toc:nil
#+DRAWERS: LATEXMACROS ...
:LATEXMACROS:
##html:<div style="display: none">##
\(
\global\def\mymacro{...}
\global\def\mymacrow2args#1#2{...}
...
\)
##html:</div>##
:END:
#+TOC: headlines
This works around the following problems:
We have to use a math environment (here \( ... \)), otherwise Org escapes the TeX syntax.
We cannot use \newcommand, because LaTeX expects them to be in the preamble and MathJaX does not receive it. \newcommand can be used outside of the preamble, but then LaTeX (unlike MathJax) restricts the defined macros to the current math environment. We usually want to use them anywhere in the file.
We cannot use a plain \def because it behaves like \newcommand in terms of scoping (global for MathJax, local for LaTeX). We cannot use \xdef either because MathJax does not know it.
MathJax does not know \global but that won't prevent it from using \def which is global anyway. However, it will print a red warning for each \global in the web page. To get rid of them, we put the math environment inside an undisplayed HTML section.
For MathJax, the macros won't be defined in time for the table of content in its default location. If you use macros in headlines and want a TOC, disable the default with #+OPTIONS: toc:nil and manually add it after the drawer with #+TOC: headlines.
Caveats:
It's not possible to preview latex fragments which use custom macros, because the small TeX file Org build won't include our environment.
Unlike \newcommand, \def silently replaces anything. Also, its syntax is slightly different.
The math environment takes up some vertical space in the output of pdflatex, so we have to put it where that doesn't matter (e.g. before the first headline).
This is probably really version dependent:
Org mode may get better at exporting LaTeX macros (e.g. sending them to MathJax by being smarter when parsing #+LATEX_HEADER, providing a new export option, not escaping \newcommand and putting those into a correctly handled preamble).
MathJax may start accepting \xdef as an alias of \def or ignoring \global (so that the HTML section trick is not needed anymore).

I figured out how to do it myself. Note that this is perhaps not the most elegant solution since it does not place the latex part in the beginning of the latex file (i.e. outside \begin{document}), but it works well enough for me.
(setq org-export-blocks
(cons '(latexmacro org-export-blocks-latexmacro) org-export-blocks))
(defun org-export-blocks-latexmacro (body &rest headers)
(message "exporting latex macros")
(cond
((eq org-export-current-backend 'html) (concat "\\(" body "\\)"))
((eq org-export-current-backend 'latex) body)
(t nil))
)

Alternative solution (not stand-alone), using Org's dynamic blocks.
It has none of the caveats of my original solution (because it generates what Org actually expects for LaTeX or HTML)
It's possible to edit the macros in LaTeX mode (C-c C-')
Callback
Create a file named org-dblock-write:block-macro.el with the following content and add it to Emacs' load path.
(defun org-dblock-write:block-macro (params)
(let ((block-name (or (plist-get params :from) "macros"))
(org-buf (current-buffer)))
(with-temp-buffer
(let ((tmp-buf (current-buffer)))
(set-buffer org-buf)
(save-excursion
(org-babel-goto-named-src-block block-name)
(org-babel-mark-block)
(let ((mblock-begin (region-beginning))
(mblock-end (region-end)))
(set-buffer tmp-buf)
(insert-buffer-substring org-buf mblock-begin mblock-end)))
(set-buffer org-buf)
(insert "#+BEGIN_HTML\n\\(\n")
(insert-buffer-substring tmp-buf)
(insert "\\)\n#+END_HTML\n")
(set-buffer tmp-buf)
(beginning-of-buffer)
(while (re-search-forward "^" nil t)
(replace-match "#+LATEX_HEADER: " nil nil))
(set-buffer org-buf)
(insert-buffer-substring tmp-buf)))))
Org file
Somewhere in the file, create:
A LaTeX source block named "macros" containing your macros
An empty block-macro dynamic block
You can change the name of the source block, and use a :from <custom-name> header argument in the dynamic block. Also, note the :exports none in the source block (usually you don't want to export the LaTeX source).
#+NAME: macros
#+BEGIN_SRC latex :exports none
\newcommand\a{a}
\def\b{b}
\DeclareMathOperator\c{c}
#+END_SRC
#+BEGIN: block-macro
#+END:
Now use C-c C-c with the point on the dynamic block, and it will update to:
#+BEGIN: block-macro
#+BEGIN_HTML
\(
\newcommand\a{a}
\def\b{b}
\DeclareMathOperator\c{c}
\)
#+END_HTML
#+LATEX_HEADER: \newcommand\a{a}
#+LATEX_HEADER: \def\b{b}
#+LATEX_HEADER: \DeclareMathOperator\c{c}
#+LATEX_HEADER:
#+END:
Do this whenever the macros are modified.

I usually have a file with many custom definitions which I reuse for many documents and I want to use it also in my org documents.
The following is a modification of Blout's answer, so please read his answer for more info.
Define macro
(defun org-dblock-write:insert-latex-macros (params)
(let ((text)
(file (plist-get params :file)))
(with-temp-buffer
(insert-file file)
(setq text (split-string (buffer-string) "\n" t)))
(insert (mapconcat (lambda (str) (concat "#+LATEX_HEADER: " str)) text "\n"))
(insert "\n#+BEGIN_HTML\n\\(\n")
(insert (mapconcat 'identity text "\n"))
(insert "\n\\)\n#+END_HTML")))
Usage
File macros.tex:
\newcommand\a{a}
\def\b{b}
\DeclareMathOperator\c{c}
In org file:
#+BEGIN: insert-latex-macros :file "macros.tex"
#+BEGIN_HTML
\(
\newcommand\a{a}
\def\b{b}
\DeclareMathOperator\c{c}
\)
#+END_HTML
#+LATEX_HEADER: \newcommand\a{a}
#+LATEX_HEADER: \def\b{b}
#+LATEX_HEADER: \DeclareMathOperator\c{c}
#+LATEX_HEADER:
#+END:

Related

Disable title in org latex export

Is it possible to completely disable the title, i.e. not even \title{}, when export org file to latex? I am using org mode to write paper the latex template provided by the publisher does not allow \title{} command appears before \begin{document}
I tried many solutions found online but neither of them works with the latex template I am using. Currently, I put #+BIND: org-latex-title-command " in my org file. From the source code in ox-latex, I found the following code inside org-latex-template (contents info):
;; Title and subtitle.
(let* ((subtitle (plist-get info :subtitle))
(formatted-subtitle
(when subtitle
(format (plist-get info :latex-subtitle-format)
(org-export-data subtitle info))))
(separate (plist-get info :latex-subtitle-separate)))
(concat
(format "\\title{%s%s}\n" title
(if separate "" (or formatted-subtitle "")))
(when (and separate subtitle)
(concat formatted-subtitle "\n"))))
Does this mean that there is no way to get rid of the \title{} command in the exported latex file?
Thanks for your assistance!
I came up with this little advice function that removes the \title{...} line from the output:
(defun my-org-latex-remove-title (str)
(replace-regexp-in-string "^\\\\title{.*}$" "" str))
(advice-add 'org-latex-template :filter-return 'my-org-latex-remove-title)

My Emacs mode does not highlight keywords

I am trying to write an Emacs major mode but it is not working; specifically, my keywords are not being displayed in keyword font face. I have tried to follow the tutorials but I must be doing something wrong. I know a little Lisp but I do not know Emacs scripting.
My Emacs mode script:
;; emacs mode for OldRope
;; does no work for some reason
(setq oldrope-directive-keywords-regexp (regexp-opt '("page" "link" "goto" "act" "end" "div" "span" "include")))
(defvar oldrope-font-lock-defaults '((
(oldrope-directive-keywords-regexp . font-lock-keyword-face))))
(define-derived-mode oldrope-mode fundamental-mode
"oldrope mode"
"Major mode for editing OldRope games"
(setq comment-start "/*")
(setq comment-end "*/")
(setq font-lock-defaults oldrope-font-lock-defaults))
(provide 'oldrope-mode)
Test file:
$[page start]$ Hello $[link]$ Click me $[act]$ That is right. $[end]$
(For context, this is part of https://github.com/martinellison/oldrope but that is not really relevant to the question).
You need this - the rest is OK:
(defvar oldrope-font-lock-defaults
`(((,oldrope-directive-keywords-regexp . font-lock-keyword-face))))
By simply quoting the list you were not evaluating oldrope-directive-keywords-regexp - your quoted list just had that symbol as its car.
Using either backquote (`) plus comma (,) or (list (list (cons oldrope-directive-keywords-regexp 'font-lock-keyword-face))) you evaluate that variable and use its value in the resulting list.

Emacs: How to switch mode after typing certain string?

I am writing R Markdown (.Rmd) file with a lot of LaTeX contents. The major mode is Markdown-mode. But what I want is that: when I try to type some LaTeX commands between $$, I want to automatically turn on the LaTeX major mode, and after I end the LaTeX chunk with $$ or $, it can turn off LaTeX major mode and turn on Markdown-mode again.
The inline format for LaTeX is
$\alpha$
The equation(displaymath) format for LaTeX is
$$
\alpha + \beta
$$
A similar example is when I was writing a .Rnw file, the major mode is LaTeX, but when I edit the R
code chunk:
<<>>=
y <- 1000
#
between <<>>= and #, it turns on the ESS mode.
So can anyone help me to do the similar stuff in Markdown-LaTeX case? Thanks!
Updates after Inaimathi's answer:
Following http://www.emacswiki.org/emacs/MultipleModes#toc6, I need to modify the two-mode-mode.el
- (if (string= to-mode mode-name)
+ (if (string= to-mode major-mode)
and for emacs 24
- (make-local-hook 'post-command-hook)
Then, by Inaimathi, I put the following in my .emacs:
(require 'two-mode-mode)
(setq default-mode (list "Markdown" 'markdown-mode)
second-modes (list (list "LaTeX" "\\\[" "\\\]" 'latex-mode)))
Then the major mode switches between \[ and \].
If you're ok with your major mode changing as you navigate, two-mode-mode should be able to do what you need. You need to include that .el, then add a block that looks something like
(require 'two-mode-mode)
(setq default-mode (list "Haskell" 'haskell-mode)
second-modes (list (list "Markdown" "\[markdown|" "|\]" 'markdown-mode)))
to your ~/.emacs. The above is what I do to highlight markdown blocks while editing Elm code. For your particular use case, you'd probably need
(require 'two-mode-mode)
(setq default-mode (list "Markdown" 'markdown-mode)
second-modes (list (list "Latex" "\$\$" "\$\$" 'latex-mode)
(list "Latex" "<<>>=" "#" 'latex-mode)))
Instead. This is completely untested, includes no warranty, etc etc.
Ideally, what I'd like in that situation is for the rest of the buffer to keep markdown-mode highlighting, and have just the particular region get highlighted in latex-mode or whatever. Near as I can tell, there isn't a ready, general solution for that, but if you're up for some Elisp hacking, you could give this a read and see what you can come up with.

Indent code in org-babel src blocks

In an org-mode file, with code like the following:
#+begin_src emacs-lisp
(add-to-list 'org-tab-before-tab-emulation-hook
(lambda ()
(when (within-the-body-of-a-begin-src-block)
(indent-for-tab-command--as-if-in-lisp-mode))))
#+end_src
I would like the TAB key to indent the code as it would if it were in a buffer in lisp mode.
What I need is:
A way to figure out whether the cursor is within a src block. It needs to not trigger when on the header line itself, as in that case the default org folding should take place.
A way to indent the code according to the mode (emacs-lisp in this case) specified in the header.
Org can already syntax highlight src blocks according to mode, and the TAB hooks are there. This looks do-able.
Since Emacs 24.1 you can now set the following option:
(setq org-src-tab-acts-natively t)
...and that should handle all src blocks.
Just move point into the code block and press C-c '
This will pop up a buffer in elisp-mode, syntax higlighting ad all...
Here's a rough solution:
(defun indent-org-src-block-line ()
"Indent the current line of emacs lisp code."
(interactive)
(let ((info (org-babel-get-src-block-info 'light)))
(when info
(let ((lang (nth 0 info)))
(when (string= lang "emacs-lisp")
(let ((indent-line-function 'lisp-indent-line))
(indent-for-tab-command)))))))
(add-to-list 'org-tab-before-tab-emulation-hook
'indent-org-src-block-line)
It only handles emacs-lisp blocks. I've only tested with the src block un-indented (not the org default).
It is tough in general to make one mode work inside another - many keyboard commands will conflict. But some of the more basic strokes, like tab for indent, newline, commenting (org will comment the lisp code with #, which is wrong) seem like they could be made to work and would have the largest impact.
(defun my/org-cleanup ()
(interactive)
(org-edit-special)
(indent-buffer)
(org-edit-src-exit))
should do it, where `indent-buffer' is defined as:
(defun indent-buffer ()
(interactive)
(indent-region (point-min) (point-max)))

Sync Emacs AUCTeX with Sumatra PDF

With these lines in my init.el I am able to sync the Emacs LaTeX buffer with Sumatra:
(setq TeX-source-correlate-mode t)
(setq TeX-source-correlate-method 'synctex)
(setq TeX-view-program-list
'(("Sumatra PDF" ("\"C:/bin86/SumatraPDF/SumatraPDF.exe\" -reuse-instance"
(mode-io-correlate " -forward-search %b %n ") " %o"))))
(setq TeX-view-program-selection
'(((output-dvi style-pstricks) "dvips and start") (output-dvi "Yap")
(output-pdf "Sumatra PDF") (output-html "start")))
To set a double click on the PDF to get me to the related LaTeX code, I also set in Sumatra options Set inverse search command line to:
"c:\bin86\GNU Emacs 24.2\bin\emacsclient.exe" --no-wait +%l "%f"
Despite the sync works, I’d like to code it differently.
If I didn’t set the last expression, (setq TeX-view-program-selection..., I would get the default values, which are the same as above, apart from the value for the PDF output that would be: (output-pdf "start").
I’d like to change this one to "Sumatra PDF" and leave the other values to their default, that is, I’d like to ask Emacs the default values for the viewers and change only the PDF value.
It is mostly an ELisp question concerning the manipulation of the variable TeX-view-program-selection.
Thanks for helping.
P.S. Please tell me if this question is best fit on tex.stackexchange
Update based on lunaryorn comments/answer
To update TeX-view-program-selection I could use:
(assq-delete-all 'output-pdf TeX-view-program-selection)
(add-to-list 'TeX-view-program-selection '(output-pdf "Sumatra PDF"))
The first line is optional, but it makes the list look "cleaner".
In both cases (with or without assq-delete-all) I now need to insert the code in the proper hook, since TeX-view-program-selection is void in init.el.
My credits to lunaryorn for suggestions! I am repackaging the steps involved to the benefits of the others.
Emacs side
Add to your init.el:
(setq TeX-PDF-mode t)
(setq TeX-source-correlate-mode t)
(setq TeX-source-correlate-method 'synctex)
(setq TeX-view-program-list
'(("Sumatra PDF" ("\"path/to/SumatraPDF/SumatraPDF.exe\" -reuse-instance"
(mode-io-correlate " -forward-search %b %n ") " %o"))))
(eval-after-load 'tex
'(progn
(assq-delete-all 'output-pdf TeX-view-program-selection)
(add-to-list 'TeX-view-program-selection '(output-pdf "Sumatra PDF"))))
Sumatra side
In Settings->Options dialog set Set inverse search command line to:
"path\to\GNU Emacs ver\bin\emacsclient.exe" --no-wait +%l "%f"
How to use
In your LaTeX document in Emacs type C-c C-v or double click the related PDF in Sumatra and ... enjoy))
Use add-to-list instead of setq. See C-h f add-to-list for more information.
TeX-view-program-selection is defined in tex.el, so you'll need to execute this code after this library is loaded:
(eval-after-load 'tex
'(progn
(assq-delete-all 'output-pdf TeX-view-program-selection)
(add-to-list 'TeX-view-program-selection '(output-pdf "Sumatra PDF"))))
I was driven nearly mad by the quoting conventions for windows ->emacs
If you install SumatraPDF in the default place, then this works on windows 8.1
(setq TeX-view-program-list
'(("Sumatra PDF" ("\"C:/Program Files (x86)/SumatraPDF/SumatraPDF.exe\" -reuse-instance"
(mode-io-correlate " -forward-search %b %n ") " %o")))))
That's an hour or so I'll never get back :)
I have prepared a batch file, Emacs_SumatraPDF.bat.
It works perfect with sumatra-forward.el to realize forward and backward search.
For example:
Download
http://www.ai.soc.i.kyoto-u.ac.jp/~shi/files/Emacs_SumatraPDF.bat
http:/william.famille-blum.org/software/sumatra/sumatra-forward.el
Prepare
put Emacs_SumatraPDF.bat and SumatraPDF.exe -->
%Emacs_Home%/bin.
put sumatra-forward.el --> %Emacs_Home%/site-lisp
Usage
;Emacs_Home=C:/Program Files (x86)/GNU Emacs 23.4
;~\.emacs add following information
;;; Emacs_SumatraPDF.bat
;; #info: pdf viewer
; #refer:
(setq TeX-view-program-list '(
("Sumatra" "C:/Program Files (x86)/GNU Emacs 23.4/bin/Emacs_SumatraPDF.bat
%o %t %n") ))
(setq TeX-view-program-selection '(
(output-pdf "Sumatra")
(output-dvi "Yap")
((output-dvi style-pstricks) "dvips and start")
(output-html "start")))
;;; sumatra-forward.el
;; #info: forward search.
; #refer: http:/william.famille-blum.org/blog/static.php?page=static081010-000413
(require 'sumatra-forward)
That is all.
Besides
Emacs 4 Latex Support under Windows 7 for newcomer for Emacs.
http://chunqishi.github.io/emacs4ls/
It's worth mentioning that Set inverse search command line is invisible in the Settings->Options dialog by default. To show this option field, go to Settings->Advanced options or open SumatraPDF-settings.txt and turn on EnableTeXEnhancements = true.