[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [O] [New exporter] custom emphasis in org-emphasis-alist
From: |
Gregor Kappler |
Subject: |
Re: [O] [New exporter] custom emphasis in org-emphasis-alist |
Date: |
Thu, 14 Feb 2013 18:42:12 +0100 |
User-agent: |
Notmuch/0.15.1+13~g7264732 (http://notmuchmail.org) Emacs/24.3.50.1 (i686-pc-linux-gnu) |
Hi Nicolas,
thanks for your replies. I can see that for org syntax stability and to
prevent parsing hassle using a variety of characters for emphasis is not
desireable. On the other hand, org-emphasis-alist had several advantages that
seem not possible with your suggestions.
When writing, I frequently mark up and fontify text for review or important
text parts (each, ? and ! used ~1000 times in my org files). The fontification
in org provided a perfect overview of what still needs attention.
> For additional syntax, a better option would be to define a macro:
>
> #+MACRO: excl @@html:<span class="org-exclamation">@@$1@@html:</span>@@
>
> Then use it within the buffer:
>
> A paragraph and {{{excl(some *bold* text within a special
> container)}}}.
This solution is charactery/wordy but I could work with some editing sugar
(abbrevs, remove-macro-keys,...). Yet I loose the fontification feature that I
appreciate highly.
For now, I took the road of adding a filter as you suggested, and made it
configurable with format strings for latex and html. Also, I implemented org
highlighting (borrowing from `org-set-emph-re' and `org-do-emphasis-faces').
This solution now works for me. If anyone else has custom emphasis markers,
and wants to keep them (like I did) the following code might be usable.
Thank you very much for your help!
Gregor
Your markup filter code did not replace multiple occurences and had hard-coded
regexps, so I adapted your markup code:
#+begin_src emacs-lisp
(require 'ox)
(defun gk-emphasis-markup (text backend info)
(let ((formats (assoc backend gk-org-export-emphasis)))
(when formats
(let ((start 0) (result ""))
(while (string-match gk-org-emph-re text start)
(setq result
(concat result
(substring text start (match-beginning 2))
(format (cadr (assoc (match-string 3 text) formats))
(match-string 4 text))))
(setq start (- (match-end 0) 1)))
(concat result
(if
(substring text start (length text))
""))))))
(add-to-list 'org-export-filter-plain-text-functions 'gk-emphasis-markup)
#+end_src
The formating strings are configured
#+begin_src emacs-lisp
(setq gk-org-export-emphasis
'((html . (("?" "<span class=\"org-question\">%s</span>")
("!" "<span class=\"org-exclamation\">%s</span>")
("#" "")))
(latex . (("?" "\\mycheck{%s}")
("!" "\\myexcl{%s}")
("#" "")))))
#+end_src
Org highlighting for the custom emphasis list (adapted from `org-set-emph-re')
#+BEGIN_SRC emacs-lisp :tangle "~/Documents/Programme/elisp/my-org-mode.el"
(setq gk-org-emphasis-alist
(quote (
("?" gk-org-question)
("!" gk-org-exclamation)
("#" font-lock-comment-face))))
(setq gk-org-emph-re
(let* ((e org-emphasis-regexp-components)
(pre (car e))
(post (nth 1 e))
(border (nth 2 e))
(body (nth 3 e))
(nl (nth 4 e))
(body1 (concat body "*?"))
(markers (mapconcat 'car gk-org-emphasis-alist ""))
(vmarkers (mapconcat
(lambda (x) (if (eq (nth 4 x) 'verbatim) (car x) ""))
gk-org-emphasis-alist "")))
;; make sure special characters appear at the right position in the class
(if (string-match "\\^" markers)
(setq markers (concat (replace-match "" t t markers) "^")))
(if (string-match "-" markers)
(setq markers (concat (replace-match "" t t markers) "-")))
(if (string-match "\\^" vmarkers)
(setq vmarkers (concat (replace-match "" t t vmarkers) "^")))
(if (string-match "-" vmarkers)
(setq vmarkers (concat (replace-match "" t t vmarkers) "-")))
(if (> nl 0)
(setq body1 (concat body1 "\\(?:\n" body "*?\\)\\{0,"
(int-to-string nl) "\\}")))
;; Make the regexp
(concat "\\([" pre "]\\|^\\)"
"\\("
"\\([" markers "]\\)"
"\\("
"[^" border "]\\|"
"[^" border "]"
body1
"[^" border "]"
"\\)"
"\\3\\)"
"\\([" post "]\\|$\\)")))
#+END_SRC
The emphasis function (adapted `org-do-emphasis-faces') then is added as
font-lock
#+BEGIN_SRC emacs-lisp :tangle "~/Documents/Programme/elisp/my-org-mode.el"
(defun gk-org-do-emphasis-faces (limit)
"Run through the buffer and add overlays to emphasized strings."
(let (rtn a)
(while (and (not rtn) (re-search-forward gk-org-emph-re limit t))
(if (not (= (char-after (match-beginning 3))
(char-after (match-beginning 4))))
(progn
(setq rtn t)
(setq a (assoc (match-string 3) gk-org-emphasis-alist))
(font-lock-prepend-text-property (match-beginning 2) (match-end 2)
'face
(nth 1 a))
(and (nth 4 a)
(org-remove-flyspell-overlays-in
(match-beginning 0) (match-end 0)))
(add-text-properties (match-beginning 2) (match-end 2)
'(font-lock-multiline t org-emphasis t))
(when org-hide-emphasis-markers
(add-text-properties (match-end 4) (match-beginning 5)
'(invisible org-link))
(add-text-properties (match-beginning 3) (match-end 3)
'(invisible org-link)))))
(backward-char 1))
rtn))
(font-lock-add-keywords
'org-mode '(gk-org-do-emphasis-faces))
#+END_SRC
Maybe the duplication of code could be prevented by including functions
`org-set-emph-re' and `org-do-emphasis-faces' with dynamical scoping?
Nicolas Goaziou <address@hidden> writes:
> Hello,
>
> Gregor Kappler <address@hidden> writes:
>
>> I am currently migrating my system and contribute my first stop:
>> custom emphasis characters that I use extensively:
>> - "!" is used for exclamations,
>> - "?" for questions, and
>> - "#" for in-text comments that I do not want exported.
>
> Emphasis characters are now hard-coded. You cannot change them, though,
> you can change how each back-end interprets them.
>
> We are solidifying Org syntax for parsing purposes. Allowing variable
> markup is asking for trouble. The plan is to make `org-emphasis-alist'
> a defconst.
>
> On the other hand, you may be able to parse custom markup with the help
> of a filter:
>
> #+begin_src emacs-lisp
> (defun my-special-markup (text backend info)
> (when (and (org-export-derived-backend-p backend 'html)
> (string-match "\\([ ('\"{]\\|^\\)\\(\\([?!#]\\)\\([^
> ,\"']\\|[^
> ,\"'].*?\\(?:
> .*?\\)\\{0,1\\}[^
> ,\"']\\)\\3\\)\\([- .,:!?;'\")}\\]\\|$\\)"
> text))
> (format (cond ((equal (match-string 3 text) "?")
> "<span class=\"org-question\">%s</span>")
> ((equal (match-string 3 text) "#") "<!--%s-->")
> (t "<span class=\"org-exclamation\">%s</span>"))
> (match-string 4 text))))
> (add-to-list 'org-export-filter-plain-text-functions 'my-special-markup)
> #+end_src
>
>
> Regards,
>
> --
> Nicolas Goaziou