8b53a1654f
Finally getting around to adding nicer quotes from Artur's Endless Parenthesis blog. Org is getting prettier and prettier.
270 lines
11 KiB
Org Mode
270 lines
11 KiB
Org Mode
#+TITLE: Org As A Word Processor
|
||
#+AUTHOR: Howard X. Abrams
|
||
#+DATE: 2020-09-10
|
||
#+FILETAGS: :emacs:
|
||
|
||
A literate programming file for making Org file more readable.
|
||
# *Note:* After each change, /tangle it/ to the source destination with ~C-c C-v t~.
|
||
|
||
#+BEGIN_SRC emacs-lisp :exports none
|
||
;;; ha-org-word-processor.org --- A literate programming file for making Org file more readable. -*- lexical-binding: t; -*-
|
||
;;
|
||
;; Copyright (C) 2020 Howard X. Abrams
|
||
;;
|
||
;; Author: Howard X. Abrams <http://gitlab.com/howardabrams>
|
||
;; Maintainer: Howard X. Abrams
|
||
;; Created: September 10, 2020
|
||
;;
|
||
;; This file is not part of GNU Emacs.
|
||
;;
|
||
;; *NB:* Do not edit this file. Instead, edit the original literate file at:
|
||
;; ~/other/hamacs/ha-org-word-processor.org
|
||
;; Using `find-file-at-point', and tangle the file to recreate this one .
|
||
;;
|
||
;;; Code:
|
||
#+END_SRC
|
||
* Introduction
|
||
I like having org-mode files look more like editing in a word processor than having it look like programming code. But that is just me.
|
||
* General Org Settings
|
||
Since I use ellipsis in my writing... I like to /change/ how org renders a collapsed heading.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-pretty-entities t
|
||
org-ellipsis "⤵" ; …, ➡, ⚡, ▼, ↴, , ∞, ⬎, ⤷, ⤵
|
||
org-agenda-breadcrumbs-separator " ❱ "
|
||
org-src-fontify-natively t ;; Pretty code blocks
|
||
org-hide-emphasis-markers t)
|
||
#+END_SRC
|
||
** Typographic Quotes
|
||
According to [[http://endlessparentheses.com/prettify-your-quotation-marks.html][Artur Malabarba]] of [[http://endlessparentheses.com/prettify-you-apostrophes.html][Endless Parenthesis]] blog, I type a /straight quote/, ", Emacs actually inserts Unicode rounded quotes, like “this”. This idea isn’t how a file is /displayed/, but actually how the file is /made/. Time will tell if this idea works with my auxiliary functions on my phone, like [[https://play.google.com/store/apps/details?id=com.orgzly&hl=en_US&gl=US][Orgzly]] and [[https://github.com/amake/orgro][Orgro]].
|
||
|
||
Stealing his function so that “quotes” just work to insert /rounded/ quotation marks:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(define-key org-mode-map "\"" #'endless/round-quotes)
|
||
|
||
(defun endless/round-quotes (italicize)
|
||
"Insert “” and leave point in the middle.
|
||
With prefix argument ITALICIZE, insert /“”/ instead
|
||
\(meant for org-mode).
|
||
Inside a code-block, just call `self-insert-command'."
|
||
(interactive "P")
|
||
(if (and (derived-mode-p 'org-mode)
|
||
(org-in-block-p '("src" "latex" "html")))
|
||
(call-interactively #'self-insert-command)
|
||
(if (looking-at "”[/=_\\*]?")
|
||
(goto-char (match-end 0))
|
||
(when italicize
|
||
(if (derived-mode-p 'markdown-mode)
|
||
(insert "__")
|
||
(insert "//"))
|
||
(forward-char -1))
|
||
(insert "“”")
|
||
(forward-char -1))))
|
||
#+END_SRC
|
||
|
||
Stealing function for automatically adding a single quote (not in pairs):
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(define-key org-mode-map "'" #'endless/apostrophe)
|
||
|
||
(defun endless/apostrophe (opening)
|
||
"Insert ’ in prose or `self-insert-command' in code.
|
||
With prefix argument OPENING, insert ‘’ instead and
|
||
leave point in the middle.
|
||
Inside a code-block, just call `self-insert-command'."
|
||
(interactive "P")
|
||
(if (and (derived-mode-p 'org-mode)
|
||
(org-in-block-p '("src" "latex" "html")))
|
||
(call-interactively #'self-insert-command)
|
||
(if (looking-at "['’][=_/\\*]?")
|
||
(goto-char (match-end 0))
|
||
(if (null opening)
|
||
(insert "’")
|
||
(insert "‘’")
|
||
(forward-char -1)))))
|
||
#+END_SRC
|
||
Quote: “From this time forward, I shouldn’t have to worry about quotes.”
|
||
|
||
*Note:* I still need to worry about how quotes affect [[file:ha-org.org::*Spell Checking][spell checking]].
|
||
* Org Beautify
|
||
I really want to use the Org Beautify package, but it overrides my darker themes (and all I really want is headlines to behave).
|
||
|
||
First step is to make all Org header levels to use the variable font, and be the same color as the default text:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(when window-system
|
||
(let ((default-color (face-attribute 'default :foreground)))
|
||
(dolist (face '(org-level-1 org-level-2 org-level-3 org-level-4 org-level-5 org-level-6 org-level-7 org-level-8))
|
||
(set-face-attribute face nil
|
||
:foreground default-color :weight 'bold :font ha-variable-font))))
|
||
#+END_SRC
|
||
|
||
Next, we just need to change the header sizes:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(when window-system
|
||
(set-face-attribute 'org-level-1 nil :height 2.2 :inherit 'default)
|
||
(set-face-attribute 'org-level-2 nil :height 1.8 :inherit 'default)
|
||
(set-face-attribute 'org-level-3 nil :height 1.4 :inherit 'default)
|
||
(set-face-attribute 'org-level-4 nil :height 1.1 :inherit 'default))
|
||
#+END_SRC
|
||
* Superstar
|
||
Now that headers are noticeable, I have no reason to see a number of asterisks. Once I used the [[https://github.com/sabof/org-bullets][org-bullets]] package, but believe we've replaced it with [[https://github.com/integral-dw/org-superstar-mode][org-superstar-mode]], so the following is an improvement, especially with the sub-bullets:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org-superstar
|
||
:after org
|
||
:straight (:type git :protocol ssh :host github :repo "integral-dw/org-superstar-mode")
|
||
:hook (org-mode . org-superstar-mode)
|
||
:init
|
||
(setq org-superstar-headline-bullets-list '("▶")
|
||
org-superstar-special-todo-items nil
|
||
org-superstar-todo-bullet-alist t
|
||
org-superstar-prettify-item-bullets t
|
||
org-superstar-item-bullet-alist '((42 . "⊙") ; *
|
||
(43 . "⁍") ; +
|
||
(45 . "•"))))
|
||
#+END_SRC
|
||
|
||
If this works, then we get the prettier bulleted list:
|
||
|
||
* Top bullets
|
||
* Plus bullets:
|
||
+ Apples
|
||
+ Oranges
|
||
+ Bananas
|
||
* Minus bullets:
|
||
- Dogs
|
||
- Cats
|
||
- Birds
|
||
|
||
Oh, and as I indent lists, they should change the /bulleting/ in a particular sequence. If I begin with an =*= asterisk, I walk down the chain, but with the dashed bullets (my default choice), I just stay with dashed bullets. Numeric bullets should cycle:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-list-demote-modify-bullet '(("*" . "+") ("+" . "-") ("-" . "-")
|
||
("1." . "a.") ("a." . "1.")))
|
||
#+END_SRC
|
||
|
||
Since the following code does not work like I would have expected:
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq org-hide-leading-stars t)
|
||
#+END_SRC
|
||
|
||
I add a hook to standard Org, and since this is a Lisp-2, I can get away with:
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun org-hide-leading-stars ()
|
||
(let* ((keyword
|
||
`(("^\\(\\*+ \\)\\s-*\\S-" ; Do not hide empty headings!
|
||
(1 (put-text-property (match-beginning 1) (match-end 1) 'invisible t)
|
||
nil)))))
|
||
(font-lock-add-keywords nil keyword)))
|
||
|
||
(add-hook 'org-mode-hook 'org-hide-leading-stars)
|
||
#+END_SRC
|
||
* Checkboxes
|
||
According to an idea by [[https://jft.home.blog/2019/07/17/use-unicode-symbol-to-display-org-mode-checkboxes/][Huy Trần]], we can prettify the list checkboxes as well:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun ha-org-prettify-checkboxes ()
|
||
"Beautify Org Checkbox Symbol"
|
||
(push '("[ ]" . "☐") prettify-symbols-alist)
|
||
(push '("[X]" . "☒") prettify-symbols-alist)
|
||
(push '("[-]" . "☐-") prettify-symbols-alist)
|
||
(prettify-symbols-mode))
|
||
#+END_SRC
|
||
|
||
And now we can attach it to a newly loaded org files:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'org-mode-hook 'ha-org-prettify-checkboxes)
|
||
#+END_SRC
|
||
|
||
To make it more distinguishable, he also changed the colors:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defface org-checkbox-done-text
|
||
'((t (:foreground "#71696A" :strike-through t)))
|
||
"Face for the text part of a checked org-mode checkbox.")
|
||
|
||
(font-lock-add-keywords
|
||
'org-mode
|
||
`(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
|
||
1 'org-checkbox-done-text prepend))
|
||
'append)
|
||
#+END_SRC
|
||
* Padding
|
||
The [[https://github.com/TonCherAmi/org-padding][org-padding]] project looks places extra space before and after headers and blocks (essentially leading), to create a more word-processor-y experience. Great idea, however, I have spent a lot of extra time entering blank lines before and after my headers and blocks:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org-padding
|
||
:straight (:type git :protocol ssh :host github :repo "TonCherAmi/org-padding")
|
||
:hook
|
||
(org-mode . org-padding-mode)
|
||
:config
|
||
(setq org-padding-block-begin-line-padding '(0.5 . 0.3)
|
||
org-padding-block-end-line-padding '(0.1 . 0.5)
|
||
org-padding-heading-padding-alist
|
||
'((4.0 . 1.5) (3.0 . 0.5) (3.0 . 0.5) (3.0 . 0.5) (2.5 . 0.5) (2.0 . 0.5) (1.5 . 0.5) (0.5 . 0.5))))
|
||
#+END_SRC
|
||
However, I'm just going to have to write a function to clean this.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun ha-remove-superfluous-org-padding ()
|
||
(interactive)
|
||
(goto-char (point-min))
|
||
(ha-remove-org-header-padding)
|
||
(goto-char (point-min))
|
||
(ha-remove-org-block-padding))
|
||
|
||
(defun ha-remove-org-header-padding ()
|
||
;; (goto-char (point-min))
|
||
(while (re-search-forward (rx (optional bol (zero-or-more space) eol "\n")
|
||
(group bol (one-or-more "*") (one-or-more space) (one-or-more any) "\n")
|
||
(optional bol (zero-or-more space) eol "\n")) nil t)
|
||
(replace-match (match-string 1) nil :no-error)))
|
||
|
||
(defun ha-remove-org-block-padding ()
|
||
;; (goto-char (point-min))
|
||
(while (re-search-forward (rx (optional bol (zero-or-more space) eol "\n")
|
||
(group bol (zero-or-more space) "#+BEGIN" (one-or-more any) eol "\n"
|
||
(zero-or-more (group bol (zero-or-more any) eol "\n"))
|
||
bol (zero-or-more space) "#+END" (zero-or-more any) eol "\n")
|
||
(optional bol (zero-or-more space) eol "\n")) nil t)
|
||
(replace-match (match-string 1) nil :no-error)))
|
||
#+END_SRC
|
||
Now that is some complicated regular expressions.
|
||
* Pasting
|
||
I like the idea that I will paste HTML text from the clipboard and have it converted to org-formatted text:
|
||
#+BEGIN_SRC emacs-lisp :results silent
|
||
(defun ha-org-paste ()
|
||
(interactive)
|
||
(if (eq system-type 'gnu/linux)
|
||
(shell-command "xclip -t text/html -o | pandoc -r html -w org" t)))
|
||
#+END_SRC
|
||
* Presentations
|
||
The [[https://github.com/takaxp/org-tree-slide][org-tree-slide]] still seems to be the best presentation tool for Org files, but I really need to issue a pull request to fix a few warnings.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org-tree-slide
|
||
:init
|
||
(setq org-tree-slide-skip-outline-level 4)
|
||
:config
|
||
(org-tree-slide-simple-profile))
|
||
#+END_SRC
|
||
* Technical Artifacts :noexport:
|
||
Let's provide a name so that the file can be required:
|
||
#+BEGIN_SRC emacs-lisp :exports none
|
||
(provide 'ha-org-word-processor)
|
||
;;; ha-org-word-processor.el ends here
|
||
#+END_SRC
|
||
Before you can build this on a new system, make sure that you put the cursor over any of these properties, and hit: ~C-c C-c~
|
||
|
||
#+DESCRIPTION: A literate programming file for making Org file more readable.
|
||
|
||
#+PROPERTY: header-args:sh :tangle no
|
||
#+PROPERTY: header-args:emacs-lisp :tangle yes
|
||
#+PROPERTY: header-args :results none :eval no-export :comments no
|
||
|
||
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil
|
||
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil
|
||
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|