Export org special text block to Latex - emacs

My problem is to export this org-block
#+BEGIN_NOTE
some text here
#+END_NOTE
to this Latex code
\begin{bclogo}[logo=\bcattention, noborder=true, barre=none]{some text here}
\end{bclogo}
Is there a way to customize how to export in Latex this block of text?

You can keep the NOTE environment and replace it with bclogo through a latex-specific filter (I modified John's code):
(defun my/latex-process-NOTE-blocks (text backend info)
"Filter special blocks from latex export."
(when (eq backend 'latex)
(let ((text (replace-regexp-in-string "\\\\begin{NOTE}" "\\\\begin{bclogo}[logo=\\\\bcattention, noborder=true, barre=none]{" text)))
(replace-regexp-in-string "\\\\end{NOTE}" "}\\\\end{bclogo}" text))))
(eval-after-load 'ox '(add-to-list
'org-export-filter-special-block-functions
'my/latex-process-NOTE-blocks))
If you want to do this with all latex-derived backends, you can replace (eq backend 'latex) with (org-export-derived-backend-p backend 'latex).
If you want to make sure the block starts with \begin{NOTE}:
(defun string/starts-with (string prefix)
"Return t if STRING starts with prefix."
(and (string-match (rx-to-string `(: bos ,prefix) t) string) t))
(defun my/latex-process-NOTE-blocks (text backend info)
"Filter special blocks from latex export."
(when (eq backend 'latex)
(if (string/starts-with text "\\begin{NOTE}")
(let ((text (replace-regexp-in-string "\\\\begin{NOTE}" "\\\\begin{bclogo}[logo=\\\\bcattention, noborder=true, barre=none]{" text)))
(replace-regexp-in-string "\\\\end{NOTE}" "}\\\\end{bclogo}" text)))))
(eval-after-load 'ox '(add-to-list
'org-export-filter-special-block-functions
'my/latex-process-NOTE-blocks))

May I suggest to use instead something like:
#+LaTeX_HEADER: \usepackage[tikz]{bclogo}
...
#+ATTR_LATEX: :options [logo=\bcattention, noborder=true, barre=none]{some title here}
#+BEGIN_bclogo
some text here
#+END_bclogo
Using a LaTeX special block is well suited here, unless you really want to use notes.

You can do it like this with a custom block in org-mode:
+begin_bclogo
some text here
+end_bclogo
Then, use a filter to modify the export like this:
(defun ox-mrkup-filter-special-block (text back-end info)
(let ((text (replace-regexp-in-string "\\\\begin{bclogo}" "\\\\begin{bclogo}[logo=\\\\bcattention, noborder=true, barre=none]{" text)))
(replace-regexp-in-string "\\\\end{bclogo}" "}\\\\end{bclogo}" text)))
(let ((org-export-filter-special-block-functions '(ox-mrkup-filter-special-block)))
(find-file (org-export-to-file 'latex "custom.tex")))
That exports to:
\begin{bclogo}[logo=\bcattention, noborder=true, barre=none]{
some text here
}\end{bclogo}
This seems to get close to what you want. I am not sure how you could get a body in the environment. I think you would need to use an attribute to set the text in {} and then use the text as the body. That is probably not easy to implement in a filter, and would be better implemented in a custom export.

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)

Making a word partly italic in org-mode

When working in Emacs org-mode, how do I make a word part italic? I want this:
wordx
but when I try word/x/ it produces
word/x/
and word{/x/} produces
word{x}
You can do this by creating a custom link.
Simple method:
(org-add-link-type "emph" nil 'org-export-emph)
(defun org-export-emph (path desc format)
(let ((text (or desc path)))
(cond
((eql format 'html)
(format "<em>%s</em>" text))
((eql format 'latex)
(format "\\emph{%s}" text))
(t
text))))
This then allows you to write par[[emph:ti]]ally em[[emph:ph][ph]]asized words.
Better (?) method:
You only define the link type by
(org-add-link-type "emph")
and handle that link type via a generic trancoder in your exporter backend.

Adding hook on elisp function

I'm using Emacs.
Is there any way to add hook on a function?
Assume that there is a markdown-export function.
It is designed to export HTML file into current directory where current working 'markdown file' exsits.
But, I want to export HTML file into another directory. How can I do that without modification on Emacs markdown plugin (markdown-mode.el)?
This is markdown-mode.el's export function:
(defun markdown-export (&optional output-file)
"Run Markdown on the current buffer, save to file, and return the filename.
If OUTPUT-FILE is given, use that as the filename. Otherwise, use the filename
generated by `markdown-export-file-name', which will be constructed using the
current filename, but with the extension removed and replaced with .html."
(interactive)
(unless output-file
(setq output-file (markdown-export-file-name ".html")))
(when output-file
(let* ((init-buf (current-buffer))
(init-point (point))
(init-buf-string (buffer-string))
(output-buffer (find-file-noselect output-file))
(output-buffer-name (buffer-name output-buffer)))
(run-hooks 'markdown-before-export-hook)
(markdown-standalone output-buffer-name)
(with-current-buffer output-buffer
(run-hooks 'markdown-after-export-hook)
(save-buffer))
;; if modified, restore initial buffer
(when (buffer-modified-p init-buf)
(erase-buffer)
(insert init-buf-string)
(save-buffer)
(goto-char init-point))
output-file)))
=====================================================================
I have made an advice to save exported HTML at temp directory
Here is the code.
(defadvice markdown-export (around set-temp-path-for-exported-file activate)
(ad-set-arg 0 (format "%s/%s" "~/.emacs.d/temp-dir" (file-name-nondirectory buffer-file-name)))
ad-do-it)
Thanks!!!!!!!!!!!!!!
In this case you do not need to hook on this function since it already accepts the filename as an argument, unfortunately it does not accept the filename when called interactively. As a workaround you can define a simple wrapper around the function like follows
(defun my-markdown-export (&optional file)
(interactive (list (ido-read-file-name "Export as: ")))
(markdown-export file))
The advice mechanism is a bit like having hooks for any arbitrary function, but here you have actual hooks you can use, as well as a function argument which addresses your requirement directly.
So you can:
(a) Pass the function any arbitrary output filename.
(b) Use the provided markdown-before-export-hook to setq whichever variables you need to (which at a glance looks like output-file, output-buffer, and output-buffer-name).

Inline code in org-mode

Markdown allows for embedded code. How can this be done in org-mode?
I know about source-code blocks:
#+begin_example
blah-blah
#+end_example
But what I want is something like this (obviously, with the right syntax, which I do not know):
This is `embeded code`.
Can this be done in org-mode? Not possible to find that in the documentation ...
While monospaced is good enough for most cases, inline code blocks have the form src_LANG[headers]{your code}. For example, src_xml[:exports code]{<tag>text</tag>}.
Edit: Code highlighting of inline code is certainly possible, albeit with patching org.el itself: The answer given here https://stackoverflow.com/a/20652913/594138 works as advertised, turning
- Inline code src_sh[:exports code]{echo -e "test"}
Into
in html-export. And the winning answer in this post, https://stackoverflow.com/a/28059832/594138, achieves the same without the need to patch org.el, but you will have to adapt it if you don't like the optics during editing.
You can enclose the text within = or ~ signs to have it typeset in monospaced font and export it verbatim (which means it is not processed for org-specific syntax):
This is =verbatim text= or ~code~.
You'll find all information about org-mode markup elements in the relevant section of the manual.
I wrote a function which I hope will be useful to help manage the code inline.
You put this code in your init file
(defun org-insert-inline-code()
"This function insert inline code `src_lang{inline code}' \nYour buffer must contain '#+PROPERTY: header-args:lang :exports code' where `lang` can be python or an other programming language."
(interactive (if (use-region-p)
(progn
(setq start (region-beginning))
(setq end (region-end))
(goto-char start)
(if (re-search-backward "^#\\+PROPERTY: header-args:[^[:blank:]]*" 1 t 1)
(progn
(forward-char 24)
(setq org-inline-lang (word-at-point))
(goto-char start)
(insert (concat "src_" org-inline-lang "{"))
(goto-char (+ 11 end))
(insert "}")
)))
(progn
(setq start (point))
(if (re-search-backward "^#\\+PROPERTY: header-args:[^[:blank:]]*" 1 t 1)
(progn
(forward-char 24)
(setq org-inline-lang (word-at-point))
(goto-char start)
(insert (concat "src_" org-inline-lang "{} "))
(backward-char 2)
))))))
(define-key org-mode-map (kbd "C-M-,") 'org-insert-inline-code)
You put this kind of PROPERTY in the org-file
#+PROPERTY: header-args:python :exports code
The required [:exports code] is given that way and the programming language can be identify by the function too.
Insert the code in line with C-M-, (the function then search back to read the language in the PROPERTY line and insert the correct command).

Why doesn't font-lock-fontify-buffer work from elisp when it works from the minibuffer?

So I'm hacking up some elisp to test a web service, and I'm running into trouble with syntax highlighting. I'm using url-retrieve-synchronously to get an HTTP response, then editing the text to get down to just the XML I need to see. Unfortunately, syntax highlighting doesn't work in the returned buffer, even though I've set it to nxml-mode and used "font-lock-fontify-buffer" in the script. However, if I do "M-x font-lock-fontify-buffer", the highlighting works as I would expect. Is there some difference between using it in elisp and from inside emacs?
Here are the relevant parts of the script I'm putting together. I admit up front that this is the first elisp scripting I've ever done, and I'm probably doing things in a ludicrously incorrect manner, but it's all worked thus far.
(defun modality-http-request (url args request-type)
(let ((url-request-method request-type)
(url-request-extra-headers '(("Content-Type" . "application/x-www-form-urlencoded")))
(url-request-data
(mapconcat (lambda (arg)
(concat (url-hexify-string (car arg))
"="
(url-hexify-string (cdr arg))))
args
"&")))
(url-retrieve-synchronously url)))
(defun modality-http-get (url args)
(modality-http-request url args "GET"))
(defun modality-http-post (url args)
(modality-http-request url args "POST"))
(defun test-modality (test)
(interactive "s\Test: ")
(let ((buffer (modality-http-get (concat (get-modality-path) test) nil)))
(set-buffer buffer)
(setq modality-beginning (point))
(forward-paragraph)
(next-line)
(beginning-of-line)
(setq modality-end (point))
(delete-region modality-beginning modality-end)
(bf-pretty-print-xml-region)
(switch-to-buffer buffer)
(font-lock-fontify-buffer)))
(defun bf-pretty-print-xml-region ()
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
(goto-char (point-min))
(while (search-forward-regexp "\>[ \\t]*\<" nil t)
(backward-char) (insert "\n"))
(indent-region (point-min) (point-max))
))
URL uses temporary/internal buffers (recognized by the fact that their name starts with a space). They're plain normal, but some functions treat them specially: font-lock will not be activated, and the buffer will usually not be shown to the user (e.g. C-x b TAB will not show those buffers).
So either rename the buffer before enabling font-lock, or copy the text you need into another buffer whose name doesn't start with a space.