2

I found coloured headings disturbing so I (setq org-level-color-stars-only t). But now the headings are too similar to regular text, and their face is default so they can't be formatted by changing a face.

Question: how can I display all headings in uppercase without actually upcasing them?

It would be nice to have a function for toggling uppercase(dly displayed) headings.

  • Something like that can easily be done with display text property or overlays. The real difficulty is that Orgmode does similar things that will interfer. – Tobias Jun 25 at 16:19
  • @Tobias can you be more specific. I tried with overlays and it works fine so far. – jagrg Jun 26 at 12:03
  • BTW here's what I tried: (org-map-entries (lambda () (when (looking-at org-complex-heading-regexp) (overlay-put (make-overlay (match-beginning 4) (match-end 4)) 'display (upcase (match-string 4)))))) – jagrg Jun 26 at 12:07
  • @jagrg Examples are: org-columns which is not playing nicely with your approach and org-clock-display which seems to work fine with your approach. Maybe the small hickup with org-columns is acceptable. Go and post your answer. You also need to provide some means for editing the headings. Maybe, entering them (with mouse or keyboard) opens them. The overlays need to be updated if one leaves an edited heading. There are also problems with automagically updated items in the heading like todo-states. – Tobias Jun 26 at 12:17
  • Jagrg's solution works. To remove the overlays you can give them a property (overlay-put overlay 'name "org-heading-upcased") and remove them afterwards all at once with (remove-overlays nil nil 'name "org-heading-upcased"). Imo it's probably better to just temporarily use another font for the headings (to see what this would do call it with M-x set-face-font and the select org-level-1 and the new font. Too bad it doesn't seem possible to use all caps or small caps variants. You could use a font that is small caps only though. – Hubisan Jun 26 at 13:39
1

Here's my attempt with help from @Tobias and @Hubisan. You can toggle the overlay using the toggle-headline-overlay command. You can also edit the headline as usual. BTW this is a proof of concept. Expect some hiccups.

(defvar headline-overlay-p nil)
(defvar headline-overlay-point nil)

(defun edit-headline ()
  (when (and (eq major-mode 'org-mode)
              headline-overlay-p)
    ;; First, upcase the last visited headline
    (when-let (point headline-overlay-point)
       (save-excursion
         (goto-char point)
         (when (save-excursion
                 (forward-line 0)
                 (looking-at org-complex-heading-regexp))
          (let* ((beg (match-beginning 4))
                 (end (match-end 4))
                 (headline (match-string 4))
                 (ov (make-overlay beg end)))
            (overlay-put ov 'name 'upcased)
            (overlay-put ov 'display (upcase headline))))
        (setq headline-overlay-point nil)))
    ;; Then remove the overlay of the current headline
    (when (save-excursion
            (forward-line 0)
            (looking-at org-complex-heading-regexp))
      (let ((beg (match-beginning 4))
            (end (match-end 4))
            (headline (match-string 4)))
        (if (and (overlays-at beg)
                 (eq (overlay-get (car (overlays-at beg)) 'name) 'upcased))
           (let ((ov (car (overlays-in beg end))))
             (when (eq (overlay-get ov 'name) 'upcased)
               (delete-overlay ov)
               (save-excursion
                 (goto-char beg)
                 (setq headline-overlay-point
                       (line-beginning-position))))))))))

(add-hook 'post-command-hook 'edit-headline)

(defun toggle-headline-overlay ()
  (interactive)
  (org-map-entries
   (lambda ()
     (when (looking-at org-complex-heading-regexp)
       (let ((beg (match-beginning 4))
             (end (match-end 4))
             (headline (match-string 4)))
         ;; Do we have an upcase overlay?
         (if (and (overlays-at beg)
                  (eq (overlay-get (car (overlays-at beg)) 'name) 'upcased))
             ;; If so delete the overlay
             (dolist (ov (overlays-in beg end))
               (when (eq (overlay-get ov 'name) 'upcased)
                 (delete-overlay ov)
                 (setq headline-overlay-p nil)))
           ;; Otherwise add the overlay
           (let ((ov (make-overlay beg end)))
             (overlay-put ov 'name 'upcased)
             (overlay-put ov 'display (upcase headline))
             (setq headline-overlay-p t))))))))

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.