emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Gregor Kappler <g.kappler@gmx.net>
To: Nicolas Goaziou <n.goaziou@gmail.com>
Cc: emacs-orgmode@gnu.org
Subject: Re: [New exporter] custom emphasis in org-emphasis-alist
Date: Thu, 14 Feb 2013 18:42:12 +0100	[thread overview]
Message-ID: <87pq02iyh7.fsf@univie.ac.at> (raw)
In-Reply-To: <876220h8ej.fsf@gmail.com>

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 <n.goaziou@gmail.com> writes:

> Hello,
>
> Gregor Kappler <g.kappler@gmx.net> 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

      parent reply	other threads:[~2013-02-14 17:50 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-10  0:32 [New exporter] custom emphasis in org-emphasis-alist Gregor Kappler
2013-02-10  0:55 ` François Pinard
2013-02-10  8:37 ` Nicolas Goaziou
2013-02-10  9:45   ` Nicolas Goaziou
2013-02-14 17:42   ` Gregor Kappler [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87pq02iyh7.fsf@univie.ac.at \
    --to=g.kappler@gmx.net \
    --cc=emacs-orgmode@gnu.org \
    --cc=n.goaziou@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).