6

I already have a few bindings like M-g b maps to β for all the greek letters and like being able to write things like $$ ξ $$ instead of $$ \xi $$ because it's easier to read when I'm not rendering LaTeX fragments (which is most of the time).

I get blank rectangles for $$ ξ $$.

I tried switching the pdf process over to XeLaTeX so that I can include literal Greek characters in LaTeX fragments, but it still only renders blank rectangles.

(setf org-latex-pdf-process "xelatex -interaction nonstopmode %b")

Is it possible to include literal greek characters in *TeX fragments?

If not, is it possible to register a hook so that I can take Greek characters occurring inside a $$ ... $$ and replace them with the corresponding \... sequence before being handed off to the TeX process?

  • Isn't that a problem with fonts? – DoMiNeLa10 Jun 26 '17 at 19:24
  • I get the same blank rectangle for invalid TeX (e.g. $$ \fooo $$). Is there a way to get more diagnostic information out when rendering fragments (C-c C-x C-l)? – Gregory Nisbet Jun 26 '17 at 19:27
  • Check if you have a buffer named similarly to *Org LaTeX Output* it might have some useful output. – DoMiNeLa10 Jun 26 '17 at 19:31
  • Is this only a problem when going through org-mode, or does it also happen when working with a pure latex document? – Dan Jun 26 '17 at 21:21
  • 1
    $$ ... $$ is not just a LaTeX fragment: it's a math-mode LaTeX fragment. You need a math font that knows about Unicode. If you export the file to TeX (C-c C-e l l), you can try compiling the TeX file from the command line, using pdflatex or xelatex (the latter is probably a better choice nowadays, but both can be made to work). These questions are better addressed to TeX SE though. – NickD Jun 27 '17 at 0:49
6

You asked:

Is it possible to include literal greek characters in *TeX fragments?

You need the right sequence of \DeclareUnicodeCharacter-statements of Greek letters for LaTeX. Such a sequence is provided in the package alphabeta.sty on CTAN. If you install that package you also need textalpha.sty on CTAN from there.

After installing the packages an org-file with the following contents should give the output in the next figure.

#+LATEX_HEADER: \usepackage{alphabeta}

  $α = \cos(\arcsin(β)+30°)Λλεε∃∈∞$

$α = \cos(\arcsin(β)+30°)Λλεε∃∈∞$

If you always need the package alphabeta.sty for the LaTeX snippets in your org-files you can also add it to org-latex-packages-alist. If you add the package via customize-option don't forget to switch on the Snippet flag.

Alternatively you can put

(eval-after-load "org"
  '(add-to-list 'org-latex-packages-alist '("" "alphabeta" t)))

in your init-file (e.g., ~.emacs or ~/.emacs.d/init.el). With this setup you do not need the line

#+LATEX_HEADER: \usepackage{alphabeta}

anymore in your org-files.

You also asked:

If not, is it possible to register a hook so that I can take Greek characters occurring inside a $$ ... $$ and replace them with the corresponding \… sequence before being handed off to the TeX process?

There is another way if you don't like installing LaTeX packages or if the above solution does not work for you. You can use the following lisp-fragment to map the utf8 characters to LaTeX control sequences.

(defcustom org-element-latex-fragment-filters
  '(org-element-latex-replace-entities)
  "List of filter functions for LaTeX fragments.
Each filter function gets the string with the latex fragment as input and it should return the filtered string."
  :type 'hook
  :options '(org-element-latex-replace-entities)
  :group 'org-latex)

(defvar org-entities2latex-table nil
  "Hash table mapping utf8 character codes to latex sequences.")

(setq org-entities2latex-table nil)

(defun org-entities2latex-table-init ()
  "Initialize `org-entities2latex-alist' from `org-entities' and `org-entities-user'."
  (unless org-entities2latex-table
    (setq org-entities2latex-table (make-hash-table))
    (cl-loop for entity in (append org-entities-user org-entities)
         with utf8
         with char
         if (and (consp entity)
             (stringp (setq utf8 (nth 6 entity)))
             (eq (length utf8) 1)
             (> (setq char (aref utf8 0)) 127))
         do (puthash char (nth 1 entity) org-entities2latex-table)
         )))

(defun seq-last (x)
  "Return the last element of sequence x."
  (elt x (1- (length x))))

(defun org-element-latex-replace-entities (latex-fragment)
  "Replace utf8-characters with corresponding latex sequences."
  (org-entities2latex-table-init)
  (apply 'concat (seq-map
          (lambda (char)
            (let (fromhash)
              (if (and (> char 127) (setq fromhash (gethash char org-entities2latex-table)))
              (concat fromhash (and (null (eq (seq-last fromhash) ?})) "{}"))
            (string char))))
          latex-fragment)))

(defun org-element-latex-fragment-filter (latex-fragment)
  "Apply filters from `org-element-latex-fragment-filters' to the value of the LATEX-FRAGMENT element."
  (let ((value (org-element-property :value latex-fragment)))
    (dolist (filter org-element-latex-fragment-filters)
      (setq value (funcall filter value)))
    (org-element-put-property latex-fragment :value value))
  latex-fragment)

(advice-add #'org-element-latex-fragment-parser :filter-return #'org-element-latex-fragment-filter)

The function org-element-latex-replace-entities translates utf8-characters on the basis of org-mode's translation tables org-entities and org-entities-user. Those tables contain more characters than alphabeta.sty. The following Figure displays the above buffer contents with translated LaTeX fragment when the lisp code is in place. One example of the additionally shown characters is the \infty symbol at the end of the LaTeX-fragment.

entities replaced by elisp

If you like that code you can install it in your init file (most likely .emacs or .emacs.d/init.el).

  • including the \usepackage works fine, even without the explicit #+LANGUAGE: ... #+LATEX_HEADER: \usepackage{alphabeta} – Gregory Nisbet Jun 26 '17 at 23:22
  • Sorry about the wrong #+LANGUAGE: english. That was a left-over from an early experiment. For the record: If one uses #+LANGUAGE it should be #+LANGUAGE: en and not #+LANGUAGE: english. The available languages are listed in org-latex-babel-language-alist. – Tobias Jun 26 '17 at 23:27
  • @GregoryNisbet Note, that the lisp fragment is an interesting alternative because it handles more utf8 characters. – Tobias Jun 26 '17 at 23:30
  • @GregoryNisbet Thanks for your comment about #+LANGUAGE:. I've corrected that flaw now. – Tobias Jun 26 '17 at 23:41
  • @GregoryNisbet You can avoid #+LATEX_HEADER: \usepackage{alphabeta} with the help of org-latex-packages-alist. See my last edit. – Tobias Jun 27 '17 at 8:18
1

Since what you want is having a text easier to read in emacs, an option is to use prettify-symbols-mode. It is mentionned in emacs' manual:

Prettify Symbols mode is a buffer-local minor mode that replaces certain strings with more attractive versions for display purposes. For example, in Emacs Lisp mode, it replaces the string ‘lambda’ with the Greek lambda character ‘λ’. In a TeX buffer, it will replace ‘\alpha’ ... ‘\omega’ and other math macros with their Unicode characters. You may wish to use this in non-programming modes as well. You can customize the mode by adding more entries to ‘prettify-symbols-alist’. More elaborate customization is available via customizing ‘prettify-symbols-compose-predicate’ if its default value ‘prettify-symbols-default-compose-p’ is not appropriate. There is also a global version, ‘global-prettify-symbols-mode’, which enables the mode in all buffers that support it.

So it works for a buffer in latex-mode, but the latex prettifications are not applied to an org buffer.

The docstring for prettify-symbols-mode (C-h f) reads:

Toggle Prettify Symbols mode. With a prefix argument ARG, enable Prettify Symbols mode if ARG is positive, and disable it otherwise. If called from Lisp, enable the mode if ARG is omitted or nil.

When Prettify Symbols mode and font-locking are enabled, symbols are prettified (displayed as composed characters) according to the rules in ‘prettify-symbols-alist’ (which see), which are locally defined by major modes supporting prettifying. To add further customizations for a given major mode, you can modify ‘prettify-symbols-alist’ thus:

(add-hook 'emacs-lisp-mode-hook
           (lambda ()
             (push '("<=" . ?≤) prettify-symbols-alist)))

If we look at variable prettify-symbols-alist (C-h v) in an org buffer we get:

prettify-symbols-alist is a variable defined in ‘prog-mode.el’.

Its value is nil

and in a latex buffer:

prettify-symbols-alist is a variable defined in ‘prog-mode.el’.

Its value is shown below.

...

Value: (("\alpha" . 945) ("\beta" . 946) ("\gamma" . 947) ("\delta" . 948) ("\epsilon" . 1013) ...

So what we would like is to set these prettifycations to org-mode as well. Looking in file tex-mode.el we find the function tex-common-initialization that does (among many things):

(setq-local prettify-symbols-alist tex--prettify-symbols-alist)

So the latex prettifications are defined in variable tex--prettify-symbols-alist, we could just do this in our org-mode buffer.

However, this turns out not to work if there's no space between the latex macro and the $ sign. $$ \xi $$ works but $$\xi$$ does not. More importantly $\xi$ does not work, and $ \xi $ breaks org mode syntax (as pointed out by @Tobias).

Let's find out what's going on. The prettification of a symbol is performed by function prettify-symbols--compose-symbol in file prog-mode.el. It checks wether to apply fontification by calling the function stored in variable prettify-symbols-compose-predicate.

prettify-symbols-compose-predicate is a variable defined in ‘prog-mode.el’. Its value is ‘prettify-symbols-default-compose-p’

Automatically becomes buffer-local when set. This variable may be risky if used as a file-local variable.

Documentation: A predicate for deciding if the currently matched symbol is to be composed. The matched symbol is the car of one entry in ‘prettify-symbols-alist’. The predicate receives the match’s start and end positions as well as the match-string as arguments.

The defaut value is:

(defun prettify-symbols-default-compose-p (start end _match)
  "Return true iff the symbol MATCH should be composed.
The symbol starts at position START and ends at position END.
This is the default for `prettify-symbols-compose-predicate'
which is suitable for most programming languages such as C or Lisp."
  ;; Check that the chars should really be composed into a symbol.
  (let* ((syntaxes-beg (if (memq (char-syntax (char-after start)) '(?w ?_))
                           '(?w ?_) '(?. ?\\)))
         (syntaxes-end (if (memq (char-syntax (char-before end)) '(?w ?_))
                           '(?w ?_) '(?. ?\\))))
    (not (or (memq (char-syntax (or (char-before start) ?\s)) syntaxes-beg)
             (memq (char-syntax (or (char-after end) ?\s)) syntaxes-end)
             (nth 8 (syntax-ppss))))))

That is, it checks that:

  • if the first (last) character is a word or symbol constituent, the character before (after) is not,

  • if the first (last) character is not a word or symbol constituent, the character before (after) is not a punctuation or escape (frankly, it's not clear to me what it's for),

  • the third condition checks we're not inside a comment (see docstring of syntax-ppss and from that those of parse-partial-sexp).

So our problem is that $ is a word constituent in org mode (note that ?\\ is a symbol constituent). We can define a new predicate function that will decide to prettify if the char before or after is a $:

(defun prettify-symbols-org-latex-compose-p (start end _match)
  "Return true iff the symbol MATCH should be composed.
The symbol starts at position START and ends at position END.
This is based on prettify-symbols-default-compose-p, to be used for
applying latex prettifycations in org mode buffers."
  ;; Check that the chars should really be composed into a symbol.
  (let* ((syntaxes-beg (if (memq (char-syntax (char-after start)) '(?w ?_))
                           '(?w ?_) '(?. ?\\)))
         (syntaxes-end (if (memq (char-syntax (char-before end)) '(?w ?_))
                           '(?w ?_) '(?. ?\\))))
    (not (or
             (and
                ;; we don't want a $ before to stop prettification
                ;; or is for the case the char before does not exist (beginning of buffer)
                (/= (or (char-before start) ?$) ?$)
                (memq (char-syntax (or (char-before start) ?\s)) syntaxes-beg))
             (and
                ;; we don't want a $ after to stop prettification
                ;; or is for the case the char after does not exist (end of buffer)
                (/= (or (char-after end) ?$) ?$)
                (memq (char-syntax (or (char-after end) ?\s)) syntaxes-end))
             (nth 8 (syntax-ppss))))))

After having defined this, we can do:

  (add-hook 'org-mode-hook
            (lambda ()
               (require 'tex-mode)
               (setq prettify-symbols-alist tex--prettify-symbols-alist)
               (setq prettify-symbols-compose-predicate #'prettify-symbols-org-latex-compose-p)
               (prettify-symbols-mode)))

The require is for ensuring tex--prettify-symbols-alist is indeed defined before being used.

  • Note that $ \alpha $ breaks org-mode syntax. cdlatex and export don't work this way. Citation from the org manual: single ‘$’ characters are only recognized as math delimiters if the enclosed text contains at most two line breaks, is directly attached to the ‘$’ characters with no whitespace in between – Tobias Jun 27 '17 at 13:07
  • I guess it does work for $$ at least. I'll have a look at these annoying issue, thanks! – JeanPierre Jun 28 '17 at 9:31
  • @Tobias I think I fixed this. Thanx again, let me know if you find another problem. – JeanPierre Jun 28 '17 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.