emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[O] [New exporter] custom emphasis in org-emphasis-alist


From: Gregor Kappler
Subject: [O] [New exporter] custom emphasis in org-emphasis-alist
Date: Sun, 10 Feb 2013 01:32:51 +0100

Cudos for all the work that has been done on migrating to the new
exporter.  I so welcome that exporting now is approaching a clean
design!

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.

This is my org-emphasis-alist configuration:
#+BEGIN_SRC emacs-lisp
  (setq org-emphasis-alist
        (quote (("*" bold "<b>" "</b>")
                ("/" italic "<i>" "</i>")
                ("_" underline "<span style=\"text-decoration:underline;\">" 
"</span>")
                ("=" (:box t :foreground "#AAF") "<code>" "</code>" verbatim)
                ("~" org-headline-done "<u>" "</u>" verbatim)
                ("+" (:strike-through t) "<del>" "</del>")
                ("?" gk-org-question "<span class=\"org-question\">" "</span>")
                ("!" gk-org-exclamation "<span class=\"org-exclamation\">" 
"</span>")
                ("#" font-lock-comment-face "<!--" "-->"))))
#+END_SRC

These emphases are currently not working .  During debugging I found
the following to be the reason: Though
org-element-text-markup-successor recognizes emphasis by using
org-emph-re, it returns only one of a set of hard-coded symbols
(`bold', `italic', `underline', `strike-through', `code' and
`verbatim').

IMHO org-element-text-markup-successor should recognize
org-emphasis-alist.  Maybe return the face configured in the cadr of
the respective org-emphasis-alist element.  However, the drawback
would be that this would disenable "quick-and-dirty" face
specification as with (:box t :foreground "#AAF") above.

On the other hand, I do not know how plans with org-emphasis-alist
are, as caddr,... for html export and org-export-latex-emphasis-alist
probably are obsolete with the new exporter.

With the following setup, the following test case worked.  However,
changing deconsts and defuns in org-element surely is not a good
approach.  Do you have any suggestions?

Thank you all for your amazing work on orgmode,

Gregor

* Test Case
With these settings these work: the test *bold*, (invisible comment?!), and .

But these still do not work: *bold*, (\leftarrow invisible comment?!), 
!exclamation! and ?question?.  These examples stop working after the comment.

: (org-export-to-file 'my-html "test.html")

* Changes
I played around further by adding lines to
org-element-text-markup-successor
#+BEGIN_SRC emacs-lisp
  (defun org-element-text-markup-successor (limit)
    "Search for the next text-markup object.

  LIMIT bounds the search.

  Return value is a cons cell whose CAR is a symbol among `bold',
  `italic', `underline', `strike-through', `code' and `verbatim'
  and CDR is beginning position."
    (save-excursion
      (unless (bolp) (backward-char))
      (when (re-search-forward org-emph-re limit t)
        (let ((marker (match-string 3)))
          (cons (cond
                 ((equal marker "*") 'bold)
                 ((equal marker "/") 'italic)
                 ((equal marker "_") 'underline)
                 ((equal marker "+") 'strike-through)
                 ((equal marker "~") 'code)
                 ((equal marker "=") 'verbatim)
                 ((equal marker "#") 'emph-comment)
                 ((equal marker "?") 'emph-question)
                 ((equal marker "!") 'emph-exclamation)
                 (t (error "Unknown marker at %d" (match-beginning 3))))
                (match-beginning 2))))))
#+END_SRC

and then trying to define org-element-emph-comment-parser copy-pasting
org-element-italic-parser:
#+BEGIN_SRC emacs-lisp
  (defun org-element-emph-comment-parser ()
    "Parse comment object at point.

  Return a list whose CAR is `italic' and CDR is a plist with
  `:begin', `:end', `:contents-begin' and `:contents-end' and
  `:post-blank' keywords.

  Assume point is at the first # marker."
    (save-excursion
      (unless (bolp) (backward-char 1))
      (looking-at org-emph-re)
      (let ((begin (match-beginning 2))
            (contents-begin (match-beginning 4))
            (contents-end (match-end 4))
            (post-blank (progn (goto-char (match-end 2))
                               (skip-chars-forward " \t")))
            (end (point)))
        (list 'emph-comment
              (list :begin begin
                    :end end
                    :contents-begin contents-begin
                    :contents-end contents-end
                    :post-blank post-blank)))))


  (defun org-element-emph-comment-interpreter (italic contents)
    "Interpret ITALIC object as Org syntax.
  CONTENTS is the contents of the object."
    (format "#%s#" contents))

  (defun org-element-emph-exclamation-parser ()
    "Parse exclamation object at point.

  Return a list whose CAR is `italic' and CDR is a plist with
  `:begin', `:end', `:contents-begin' and `:contents-end' and
  `:post-blank' keywords.

  Assume point is at the first # marker."
    (save-excursion
      (unless (bolp) (backward-char 1))
      (looking-at org-emph-re)
      (let ((begin (match-beginning 2))
            (contents-begin (match-beginning 4))
            (contents-end (match-end 4))
            (post-blank (progn (goto-char (match-end 2))
                               (skip-chars-forward " \t")))
            (end (point)))
        (list 'emph-exclamation
              (list :begin begin
                    :end end
                    :contents-begin contents-begin
                    :contents-end contents-end
                    :post-blank post-blank)))))


  (defun org-element-emph-exclamation-interpreter (italic contents)
    "Interpret ITALIC object as Org syntax.
  CONTENTS is the contents of the object."
    (format "?%s?" contents))

  (defun org-element-emph-question-parser ()
    "Parse question object at point.

  Return a list whose CAR is `italic' and CDR is a plist with
  `:begin', `:end', `:contents-begin' and `:contents-end' and
  `:post-blank' keywords.

  Assume point is at the first # marker."
    (save-excursion
      (unless (bolp) (backward-char 1))
      (looking-at org-emph-re)
  (message "%s" (match-string 4))
      (let ((begin (match-beginning 2))
            (contents-begin (match-beginning 4))
            (contents-end (match-end 4))
            (post-blank (progn (goto-char (match-end 2))
                               (skip-chars-forward " \t")))
            (end (point)))
        (list 'emph-question
              (list :begin begin
                    :end end
                    :contents-begin contents-begin
                    :contents-end contents-end
                    :post-blank post-blank)))))

  (defun org-element-emph-question-interpreter (italic contents)
    "Interpret ITALIC object as Org syntax.
  CONTENTS is the contents of the object."
    (format "?%s?" contents))
#+END_SRC
(Considering that I only changed the defun name and emph-comment, to me this 
seems a lot of duplicate code.  I am a mere elisp novice without knowledge of 
macros - but would this not be a case to use macros or similar in order to ease 
things?)

Stealing from org-html-italic 
#+BEGIN_SRC emacs-lisp
  (add-to-list 'org-html-text-markup-alist '(emph-comment . ""))
  (add-to-list 'org-html-text-markup-alist '(emph-exclamation . "<span 
class=\"org-exclamation\">%s</span>"))
  (add-to-list 'org-html-text-markup-alist '(emph-question . "<span 
class=\"org-question\">%s</span>"))

  (defun my-emph-comment (text contents info)
    "Transcode a comment emphasis element from Org to latex.
     CONTENTS is nil.  INFO is a plist used as a communication
     channel."
    (message "comment %s" contents)
    (format (or (cdr (assq 'emph-comment org-html-text-markup-alist)) "%s") 
contents))

  (defun my-emph-exclamation (text contents info)
    "Transcode a comment emphasis element from Org to latex.
     CONTENTS is nil.  INFO is a plist used as a communication
     channel."
    (message "exclamation %s" contents)
    (format (or (cdr (assq 'emph-exclamation org-html-text-markup-alist)) "%s") 
contents))

  (defun my-emph-question (text contents info)
    "Transcode a comment emphasis element from Org to latex.
     CONTENTS is nil.  INFO is a plist used as a communication
     channel."
    ;;(fux)
    (message "question %s" contents)
    (format (or (cdr (assq 'emph-question org-html-text-markup-alist)) "%s") 
contents))

  (org-export-define-derived-backend my-html html 
    :translate-alist ((emph-comment . my-emph-comment)
                      (emph-exclamation . my-emph-exclamation)
                      (emph-question . my-emph-question)))
#+END_SRC
(again, this seems a lot of duplicate code...)

With this change, contents always was passed nil...  
So I digged further into org-element.el - and finally by experimenting found 
that adding my new elements to
#+BEGIN_SRC emacs-lisp
  (defconst org-element-recursive-objects
    '(emph-question emph-exclamation emph-comment bold italic link subscript 
radio-target strike-through superscript
           table-cell underline)
    "List of recursive object types.")
#+END_SRC
resulted in a (partly) working solution.  Yet, bold and italic occur quite 
often hard-coded in org-element.el.

-- 
Dr. Gregor Kappler

Fakultät für Psychologie 
Institut für Angewandte Psychologie: Gesundheit,
                Entwicklung, Förderung
Universität Wien
Liebiggasse 5
A-1010 Wien

http://www.univie.ac.at/Psychologie
tel: +43 1 4277 47276



reply via email to

[Prev in Thread] Current Thread [Next in Thread]