1

Or: How to put face changes in a defun?

I use AUCTeX to edit my LaTeX files and I like the way AUCTeX displays the sub- and superscripts (not only in formulas).

Not only it shifts the sub- or superscripted text up or down, it also scales it down a bit (probably to still fit in the line).

That's great, because it makes the text more clearly.

But it breaks the idea of the monospaced font. So, while working in any way with the rectangular features, the problem occurs, that the same column isn't displayed at the same visual position, which is a bit annoying.

A short demonstration: All cells are filled with the same amount of chars:

\begin{tabular}{cc}
$f^{oo}$ & $b_{ar}$ \\ 
(f|{oo}) & (b|{ar}) \\
\end{tabular}

but won't displayed this way in AUCTeX (per default).

So I thought, I could write a function to turn the sub- and superscript feature on and off.

As described at Emacs AucTex Latex syntax prevents monospaced font one can give emacs permanent rules, by putting this in your init.el:

(setq font-latex-script-display (quote (nil))) 

which prevents the shifting, and:

(custom-set-faces
 '(font-latex-subscript-face ((t nil)))
 '(font-latex-superscript-face ((t nil)))
 )

which turns off the scaling.

So I tried things like:

(defun toggle-LaTeX-rectangular-edit-ready-mode ()
  (interactive)
  (if (equal truncate-lines nil)
      (progn
    (setq-default font-latex-subscript-face '(:height 80)) ; doesn't work
    (set-face-font font-latex-superscript-face '(:height 80)) ; also doesn't work 
    (setq font-latex-superscript-face ((t nil))) ; also doesn't work 
    (setq truncate-lines t)
    (message "LaTeX-rectangular-edit-ready-mode has been switched on")
    )
    (progn
      (normal-mode)
      (setq truncate-lines nil)
      (message "LaTeX-rectangular-edit-ready-mode has been switched off")
      )
    )
  )

without any success.

My current workaround:

(defun toggle-LaTeX-rectangular-edit-ready-mode ()
  (interactive)
  (if (equal truncate-lines nil)
      (progn
    (text-mode)
    (setq truncate-lines t)
    (message "LaTeX-rectangular-edit-ready-mode has been switched on")
    )
    (progn
      (normal-mode)
      (setq truncate-lines nil)
      (message "LaTeX-rectangular-edit-ready-mode has been switched off")
      )
    )
  )

is hopefully just a miserable intermediate result.

So how can I achieve toggling face changes?

Solution (not only intermediate?)

As giordano mentioned, set-face-attribute helps us adjusting the height of the sub- and superscripted text.

We complete the defun with font-latex-script-display. At first, I thought, we have to restart the major-mode after using font-latex-script-display, but all we need is a font-lock-fontify-buffer call.

As I said, I need this function mostly for manipulating text rectangularly, so that's why I toggle truncate-lines (I use visual-line-mode). To make the function perfect, we add recenter, because by toggling truncate-lines the cursor appears in a different place, recenter helps us finding the cursor, so we get finally:

(defun toggle-LaTeX-rectangular-edit-ready-mode ()
  (interactive)
  (if (equal truncate-lines nil)
      (progn
    (set-face-attribute 'font-latex-subscript-face nil :height 1.0)
    (set-face-attribute 'font-latex-superscript-face nil :height 1.0)
    (setq font-latex-script-display (quote (nil)))
    (font-lock-fontify-buffer)
    (setq truncate-lines t)
    (recenter)
    (message "LaTeX-rectangular-edit-ready-mode has been switched on"))
    (progn
      (set-face-attribute 'font-latex-subscript-face nil :height 0.8)
      (set-face-attribute 'font-latex-superscript-face nil :height 0.8)
      (setq font-latex-script-display (quote ((raise -0.3) raise 0.3)))
      (font-lock-fontify-buffer)
      (setq truncate-lines nil)
      (recenter)
      (message "LaTeX-rectangular-edit-ready-mode has been switched off")))
  )

which I'll bind to a fn key.

1

Use set-face-attribute in order to change a face on-the-fly, not setq:

(defun toggle-LaTeX-rectangular-edit-ready-mode ()
  (interactive)
  (if (equal truncate-lines nil)
      (progn
    (set-face-attribute
     'font-latex-subscript-face nil
     :height 1.0)
    (set-face-attribute
     'font-latex-superscript-face nil
     :height 1.0)
    (setq truncate-lines t)
    (message "LaTeX-rectangular-edit-ready-mode has been switched on"))
    (progn
      (set-face-attribute
       'font-latex-subscript-face nil
       :height 0.8)
      (set-face-attribute
       'font-latex-superscript-face nil
       :height 0.8)
      (setq truncate-lines nil)
      (message "LaTeX-rectangular-edit-ready-mode has been switched off"))))
  • set-face-attribute is great, I did not thought, one can change the faces instantly, thank you very much, it works great. But it doesn't toggles the vertical shifting. Anyway, I ask: “So how can I achieve toggling face changes?” and also: “Or: How to put face changes in a defun?”. That's why I'll mark your answer as the accepted one. – Kurt Hesselbart Oct 8 '15 at 3:52

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.