Doom Emacs Configuration
Table of Contents
- Useful Bindings
 - Basic Configuration
 - Org Mode
- Org General Config
 - Org Inline Images
 - Org Links
 - Org Tagging
 - Org Refile
 - Org TODO
 - Org Archive
 - Org Agenda
 - Org Fancy Priority
 - Org Notification based on calendar event
 - Org Structure Template
 - Org Capture
 - Org Export
 - HTML Export
 - Org LaTeX
 - LaTeX macro both for LaTeX and HTML export
 - Org Projects
 - Org big org-project
 - Automatically run 
startblockwhen opening org-mode files - Insert ScreenShot or Picture from Phone
 - Render Tables
 - Org Gcal
 - Custom Keybindings - 
,leader key andC-c 
 - Org Babel
- Main configuration
 - Appearance of source blocks
 - Indentation
 - Library of Babel
 - Org-Babel Matlab
 - Some functions for using Matlab with Org Babel 
,m - Remap 
ctrl-retused to execute the src block and go to the next one - Remap 
ctrl-shift-retused to execute the (matlab) src block in the background and go to the next one - Align Source Blocks
 - Helping Functions - Tangling 
,b 
 - Bibliography Management
 - LaTeX
 - Matlab
 - Mu4e
 - Doom 
init.el - Doom 
packages.el 
https://medium.com/urbint-engineering/emacs-doom-for-newbies-1f8038604e3b https://noelwelsh.com/posts/2019-01-10-doom-emacs.html https://dotdoom.netlify.com/config.html https://emacs.christianbaeuerlein.com/ https://github.com/nmartin84/.doom.d/blob/master/config.org
Documentation:
When changing init.el or package.el, tangle the files and then run doom sync.
After that, restart Emacs with spc q r.
Useful Bindings
align-regexp: equivalent of vim-easy-align. Very useful to align tables and stuff
General Bindings
spc : | 
Execute command | 
spc < | 
Switch to buffer | 
spc X | 
org-capture | 
spc s s | 
Search in buffer with swiper | 
spc s p | 
Search in project | 
spc p p | 
Switch project | 
spc p t | 
TODOs in project | 
spc o f | 
Create frame | 
spc o e | 
Toggle Eshell | 
spc n l | 
Store link | 
spc g g | 
Magit status | 
spc f r | 
Open recent file | 
spc b B | 
Switch to buffer | 
spc b d | 
Kill current buffer | 
spc b i | 
ibuffer | 
spc tab . | 
Switch to workspace | 
spc tab n | 
New workspace | 
spc tab r | 
Rename workspace | 
spc m A | 
org-archive-subtree | 
spc m I | 
org-toggle-inline-images | 
spc m d | 
org-deadline | 
spc m e | 
org-export-dispatch | 
spc m o | 
org-set-property | 
spc m s | 
org-schedule | 
spc m t | 
org-todo | 
Org-Babel Bindings
C-c C-v p | 
org-babel-previous-src-block | 
C-c C-v n | 
org-babel-next-src-block | 
C-c C-v e | 
org-babel-execute-maybe | 
C-c C-v o | 
org-babel-open-src-block-result | 
C-c C-v v | 
org-babel-expand-src-block | 
C-c C-v u | 
org-babel-goto-src-block-head | 
C-c C-v g | 
org-babel-goto-named-src-block | 
C-c C-v r | 
org-babel-goto-named-result | 
C-c C-v b | 
org-babel-execute-buffer | 
C-c C-v s | 
org-babel-execute-subtree | 
C-c C-v d | 
org-babel-demarcate-block | 
C-c C-v t | 
org-babel-tangle | 
C-c C-v f | 
org-babel-tangle-file | 
C-c C-v c | 
org-babel-check-src-block | 
C-c C-v j | 
org-babel-insert-header-arg | 
C-c C-v l | 
org-babel-load-in-session | 
C-c C-v i | 
org-babel-lob-ingest | 
C-c C-v I | 
org-babel-view-src-block-info | 
C-c C-v z | 
org-babel-switch-to-session-with-code | 
C-c C-v a | 
org-babel-sha1-hash | 
C-c C-v h | 
org-babel-describe-bindings | 
C-c C-v x | 
org-babel-do-key-sequence-in-edit-buffer | 
Evil bindings
gv | 
Selects the previous visual | 
o in visual mode | 
go to the `Other` end of the selection | 
g= and g- | 
Increase/decrement number | 
t followed by any char | 
goes “till” next character (not included) | 
f followed by any char | 
“find” next character (included) | 
yt. | 
yank until next . | 
Basic Configuration
Personal Information
;; These are used for a number of things, particularly for GPG configuration,
;; some email clients, file templates and snippets.
(setq user-full-name "Dehaeze Thomas"
      user-mail-address "dehaeze.thomas@gmail.com")
Doom Config
(setq doom-font (font-spec :family "Hack Nerd Font Mono" :size 12 :weight 'semi-light)
      doom-variable-pitch-font (font-spec :family "Hack Nerd Font Mono")
      doom-unicode-font (font-spec :family "Hack Nerd Font Mono" :size 12)
      doom-big-font (font-spec :family "Hack Nerd Font Mono" :size 19))
(setq doom-theme 'doom-gruvbox)
(setq display-line-numbers-type t)
Evil
(after! evil (map! :m "-" #'dired-jump))
Make movement keys work like they should
(define-key evil-normal-state-map (kbd "<remap> <evil-next-line>") 'evil-next-visual-line) (define-key evil-normal-state-map (kbd "<remap> <evil-previous-line>") 'evil-previous-visual-line) (define-key evil-motion-state-map (kbd "<remap> <evil-next-line>") 'evil-next-visual-line) (define-key evil-motion-state-map (kbd "<remap> <evil-previous-line>") 'evil-previous-visual-line)
Make horizontal movement cross lines
(setq-default evil-cross-lines t)
Which Key
(after! which-key
  (setq which-key-idle-delay 0.5
        which-key-idle-secondary-delay 0.01
        which-key-sort-order 'which-key-key-order-alpha))
Visual
Automatic line wrap.
(global-visual-line-mode nil)
Turn off auto-fill mode that add line breaks.
(auto-fill-mode -1) (remove-hook 'text-mode-hook 'turn-on-auto-fill) ;; turn on auto-fill for text-mode (add-hook 'text-mode-hook 'turn-on-auto-fill) (after! org ;; turn off auto-fill for org-mode (add-hook 'org-mode-hook 'turn-off-auto-fill))
Change default alert backend
(setq alert-default-style 'libnotify)
Lockfiles
(setq create-lockfiles nil)
Disable highlight of current line
(global-hl-line-mode -1)
(after! org
  (add-hook 'org-mode-hook
      (lambda()
          (hl-line-mode -1)
          (global-hl-line-mode -1))
      't
  ))
Remap jump-forward key binding
(with-eval-after-load 'better-jumper (map! :desc "Jump Forward" "C-i" #'better-jumper-jump-forward))
Magit
(setenv "GIT_ASKPASS" "git-gui--askpass") (setq magit-diff-refine-hunk 'all)
Dired
C-c C-eWritable Dired mode, when changes are doneC-c C-c. This works also withC-x C-qC-c C-rusersyncto copy file in the background+Create a directoryRRename / moveCCopydDeletemMarkUunmark all markedtinvert the selectionuunmark / undeletexactually delete files/directories marked for deletion!Execute shell command on this file, or currently marked files%mmark by patternosort by time/name(Hide details)Show git infos
(use-package! dired-narrow
  :config
  (map! :map dired-mode-map
        :n "f"
        'dired-narrow-fuzzy))
PDF-Tools
(use-package! pdf-tools :config (add-hook 'pdf-view-mode-hook (lambda() (linum-mode -1))) )
Yassnippets
(push "~/.config/doom/snippets" yas-snippet-dirs) (yas-global-mode 1)
Ox-Hugo
(defun tdh-export-everything-to-hugo ()
  "Export all the .org files in the specified directory to markdown using Hugo"
  (interactive)
  (setq org-files (directory-files (read-directory-name "Directory:" "/home/thomas/Cloud/brain/") t "org$" t))
  (while org-files
    (setq current-org-file (car org-files))
    (message "Exporting %s" current-org-file)
    (find-file current-org-file)
    (org-hugo-export-to-md)
    (setq org-files (cdr org-files))))
Org Mode
Org General Config
(setq org-directory "~/Cloud/org/") (after! org (setq org-directory "~/Cloud/org/") ;; Replace the content marker, “⋯”, with a nice unicode arrow. (setq org-ellipsis " ⤵") (setq org-default-notes-file "~/Cloud/org/refile.org") ;; Avoid accidentally editing folded regions, say by adding text after an Org “⋯”. (setq org-catch-invisible-edits 'show) ;; The following setting hides blank lines between headings which keeps folded view nice and compact. (setq org-cycle-separator-lines 0) ;; Indent according to the outline structure (setq org-startup-indented t) (setq org-startup-folded t) ;; Record the information of when the task was marked as DONE (setq org-log-done 'time) ;; begining of line on heading behavior (setq org-special-ctrl-a/e nil) )
TAB was changed to toggle only the visibility state of the current subtree, rather than cycle through it recursively. This can be reversed with:
(after! evil-org (remove-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h))
Org Inline Images
Display the real size of images and not the one set with attr_latex: :width \linewidth for instance.
(after! org (setq org-image-actual-width t))
Org Links
(after! org
  (setq org-link-abbrev-alist
    '(("bib" . "~/Cloud/brain/biblio/references.bib::%s")
      ("notes" . "~/Cloud/brain/%s.org")
      ("papers" . "~/Cloud/pdfs/%s.pdf")))
  )
Org Tagging
(after! org
  ;; Align Tags and flush right
  (setq org-tags-column -78)
  ;; Tags with fast selection keys
  (setq org-tag-alist (quote (("@home" . ?h)
                              ("@work" . ?w)
                              ("@christophe" . ?c)
                              ("@veijo" . ?v))))
  )
Org Refile
(after! org (setq org-refile-targets '((org-agenda-files . (:maxlevel . 6)))) )
Org TODO
(after! org
  ;; Tags with fast selection keys
  (setq org-todo-keywords '(
                            (sequence "TODO(t)" "NEXT(n)" "MAIL(m)" "|" "DONE(d)")
                            (sequence "READ(r)" "BKMK(b)" "EXER(x)" "|" "DONE(d)")
                            (sequence "WAIT(w@/!)" "SDAY(s)" "|" "CANC(c@/!)")
                            (sequence "QUES(q)" "|" "ANSW(a)")
                            (sequence "EXAM(e)" "IDEA(i)" "|")
                            ))
  ;; Display of the keywords
  (setq org-todo-keyword-faces
        '(("TODO" . (:foreground "#cc241d" :weight bold)) ;; red
          ("EXER" . (:foreground "#cc241d" :weight bold)) ;; red
          ("NEXT" . (:foreground "#cc241d" :weight bold)) ;; red
          ("MAIL" . (:foreground "#cc241d" :weight bold)) ;; red
          ("READ" . (:foreground "#cc241d" :weight bold)) ;; red
          ("ANSW" . (:foreground "#689d6a" :weight bold)) ;; aqua
          ("DONE" . (:foreground "#689d6a" :weight bold)) ;; aqua
          ("WAIT" . (:foreground "#d65d0e" :weight bold)) ;; orange
          ("QUES" . (:foreground "#d79921" :weight bold)) ;; yellow
          ("CANC" . (:foreground "#a89984" :weight bold)) ;; grey
          ("SDAY" . (:foreground "#98971a" :weight bold)) ;; green
          ("BKMK" . (:foreground "#98971a" :weight bold)) ;; green
          ("IDEA" . (:foreground "#98971a" :weight bold)) ;; green
          ("EXAM" . (:foreground "#98971a" :weight bold)))) ;; green
  )
Org Archive
https://gist.github.com/Fuco1/e86fb5e0a5bb71ceafccedb5ca22fcfb Archive subtrees under the same hierarchy as original in the archive files
(after! org
  (defadvice org-archive-subtree (around fix-hierarchy activate)
    (let* ((fix-archive-p (and (not current-prefix-arg)
                               (not (use-region-p))))
           (location (org-archive--compute-location org-archive-location))
           (afile (car location))
           (offset (if (= 0 (length (cdr location)))
                       1
                     (1+ (string-match "[^*]" (cdr location)))))
           (buffer (or (find-buffer-visiting afile) (find-file-noselect afile))))
      ad-do-it
      (when fix-archive-p
        (with-current-buffer buffer
          (goto-char (point-max))
          (while (> (org-current-level) offset) (org-up-heading-safe))
          (let* ((olpath (org-entry-get (point) "ARCHIVE_OLPATH"))
                 (path (and olpath (split-string olpath "/")))
                 (level offset)
                 tree-text)
            (when olpath
              (org-mark-subtree)
              (setq tree-text (buffer-substring (region-beginning) (region-end)))
              (let (this-command) (org-cut-subtree))
              (goto-char (point-min))
              (save-restriction
                (widen)
                (-each path
                  (lambda (heading)
                    (if (re-search-forward
                         (rx-to-string
                          `(: bol (repeat ,level "*") (1+ " ") ,heading)) nil t)
                        (org-narrow-to-subtree)
                      (goto-char (point-max))
                      (unless (looking-at "^")
                        (insert "\n"))
                      (insert (make-string level ?*)
                              " "
                              heading
                              "\n"))
                    (cl-incf level)))
                (widen)
                (org-end-of-subtree t t)
                (org-paste-subtree level tree-text))))))))
  )
Org Agenda
General configuration
(after! org
  ;; File to save todo items
  (setq org-agenda-files (list "~/Cloud/org/"))
  ;; Include archived files
  (setq org-agenda-archives-mode t)
  ;; Set priority range from A to C with default A
  (setq org-highest-priority ?A)
  (setq org-lowest-priority ?C)
  (setq org-default-priority ?C)
  ;; Set colours for priorities
  (setq org-priority-faces '((?A . (:foreground "#FB4934"))
                             (?B . (:foreground "#FABD2F"))
                             (?C . (:foreground "#98971A"))))
  ;; Open agenda in current window
  (setq org-agenda-window-setup 'current-window)
  (setq org-agenda-prefix-format
        '((agenda  . " %-12:c %?-12t% s")
          (todo  . "") ;; Don't show the filename for reading agenda
          (tags  . " %-12:c")
          (search . " %-12:c"))
        )
  )
Org Agenda Custom Views
(after! org-agenda
  (defun tdh-org-agenda-skip-scheduled ()
    (org-agenda-skip-entry-if 'scheduled 'deadline 'regexp "\n]+>"))
  (setq org-agenda-custom-commands
        '(("w" "Work"
           ((org-ql-block '(and (tags "@work")
                                (todo "TODO")
                                (priority "A"))
                          ((org-ql-block-header "Important TODOs")))
            (org-ql-block '(and (tags "@work")
                                (todo "TODO")
                                (priority "B"))
                          ((org-ql-block-header "TODOs")))
            (org-ql-block '(and (tags "@work")
                                (todo "TODO")
                                (priority "C"))
                          ((org-ql-block-header "Not important TODOs")))))
          ("h" "Home"
           ((org-ql-block '(and (tags "@home")
                                (todo "TODO")
                                (priority "A"))
                          ((org-ql-block-header "Things to do")))
            (org-ql-block '(and (tags "@home")
                                (todo "TODO")
                                (priority "B"))
                          ((org-ql-block-header "Things to do")))
            (org-ql-block '(and (tags "@home")
                                (todo "TODO")
                                (priority "C"))
                          ((org-ql-block-header "Things to do")))))
          ("q" "Questions to ask"
           ((org-ql-block '(and (todo "QUES")
                                (tags "@christophe"))
                          ((org-ql-block-header "Questions to Christophe")))
            (org-ql-block '(and (todo "QUES")
                                (tags "@veijo"))
                          ((org-ql-block-header "Questions to Veijo")))
            (org-ql-block '(and (todo "QUES")
                                (not (tags "@veijo" "@christophe")))
                          ((org-ql-block-header "Other Questions")))))
          ("R" "Already read Articles and Books"
           ((org-ql-block '(and (todo "DONE")
                                (level 1)
                                (tags "article" "inproceedings" "techreport" "inbook"))
                          ((org-ql-block-header "Articles")))
            (org-ql-block '(and (todo "DONE")
                                (level 1)
                                (tags "book"))
                          ((org-ql-block-header "Books")))
            (org-ql-block '(and (todo "DONE")
                                (level 1)
                                (tags "phdthesis"))
                          ((org-ql-block-header "Phd Thesis")))
            (org-ql-block '(and (todo "DONE")
                                (level 1)
                                (not (tags "article" "inproceedings" "techreport" "inbook" "book" "phdthesis")))
                          ((org-ql-block-header "Other Things"))))
           ((org-agenda-files '("~/Cloud/brain/"))))
          ("r" "Articles and Books to read"
           ((org-ql-block '(and (todo "READ")
                                (level 1)
                                (tags "article" "inproceedings" "techreport" "inbook"))
                          ((org-ql-block-header "Article to Read")))
            (org-ql-block '(and (todo "READ")
                                (level 1)
                                (tags "book"))
                          ((org-ql-block-header "Books to Read")))
            (org-ql-block '(and (todo "READ")
                                (level 1)
                                (tags "phdthesis"))
                          ((org-ql-block-header "Phd Thesis to Read")))
            (org-ql-block '(and (todo "READ")
                                (level 1)
                                (not (tags "article" "inproceedings" "techreport" "inbook" "book" "phdthesis")))
                          ((org-ql-block-header "Other Things to Read"))))
           ((org-agenda-files '("~/Cloud/brain/")))))
        )
  )
Org Fancy Priority
(use-package! org-fancy-priorities ; priority icons
  :hook (org-mode . org-fancy-priorities-mode)
  :config (setq org-fancy-priorities-list '("■" "■" "■")))
Org Notification based on calendar event
(after! org-agenda
  (setq appt-message-warning-time 5)
  (defun tdh-org-agenda-to-appt ()
    (interactive)
    (setq appt-time-msg-list nil)
    (org-agenda-to-appt))
  (tdh-org-agenda-to-appt)
                                        ; Display appointments as a window manager notification
  (setq appt-disp-window-function 'tdh-appt-display)
  (setq appt-delete-window-function (lambda () t))
  (setq tdh-appt-notification-app (concat (getenv "HOME") "/bin/appt-notification"))
  (defun tdh-appt-display (min-to-app new-time msg)
    (if (atom min-to-app)
        (start-process "tdh-appt-notification-app" nil tdh-appt-notification-app min-to-app msg)
      (dolist (i (number-sequence 0 (1- (length min-to-app))))
        (start-process "tdh-appt-notification-app" nil tdh-appt-notification-app (nth i min-to-app) (nth i msg)))))
  )
appt-notification script
TIME="$1"TODO MSG="$2" dunstify --replace=85401 "Event in $TIME minutes" "$MSG"
Org Structure Template
(after! org
  (setq org-structure-template-alist
    '(("c" . "center")
      ("C" . "comment")
      ("m" . "src matlab\n")
      ("l" . "src emacs-lisp\n")
      ("i" . "important")
      ("e" . "example")
      ("q" . "quote")
      ("s" . "src")))
)
Org Capture
Documentation:
- Template elements: https://orgmode.org/manual/Template-elements.html#Template-elements
 - Template expansion: https://orgmode.org/manual/Template-expansion.html#Template-expansion
 - Capture protocol: https://orgmode.org/manual/capture-protocol.html
 
(after! org
  (setq org-capture-templates
        (quote (("t"    ; key
                 "todo" ; name
                 entry  ; type
                 (file+headline "~/Cloud/org/work-notebook.org" "Inbox") ; target
                 "** TODO %?\n%U\n" ; template
                 )
                ("M"    ; key
                 "Meeting" ; name
                 entry  ; type
                 (file+headline "~/Cloud/org/work-notebook.org" "Meetings") ; target
                 "** %?\n%(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n" ; template
                 )
                ("m"    ; key
                 "mail" ; name
                 entry  ; type
                 (file+headline "~/Cloud/org/work-notebook.org" "Mails") ; target
                 "** TODO [#A] %?\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n%a\n" ; template
                 )
                ("pm"
                 "Org-Protocol Mail"
                 entry
                 (file+headline "~/Cloud/org/work-notebook.org" "Mails")
                 "* MAIL %:description [[message:%:link][link]]\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n\n"
                 :immediate-finish t
                 )
                ("pu"
                 "Org-Protocol Url"
                 entry
                 (file+headline "~/Cloud/org/work-notebook.org" "Inbox")
                 "* [[%:link][%:description]]\nCaptured On: %U\n\n"
                 :immediate-finish t
                 )
                ("pt"
                 "Org-Protocol text"
                 entry
                 (file+headline "~/Cloud/org/work-notebook.org" "Inbox")
                 "* %:description\nSource: %:link\nCaptured On: %U\n\n#+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n"
                 :immediate-finish t
                 )
                )))
  )
Org Export
Basic configuration:
(after! org ;; How many levels of headline to export (setq org-export-headline-levels 4) ;; Authorize BIND to set local variables (setq org-export-allow-bind-keywords t) ;; Use doc instead of odt (setq org-odt-preferred-output-format "doc") )
Some defaults:
(after! org (setq org-export-with-author t) (setq org-export-with-creator nil) (setq org-export-with-date t) (setq org-export-with-toc t) (setq org-export-with-drawers nil) (setq org-export-with-sub-superscripts nil) (setq org-export-with-todo-keywords nil) )
Do not export headline with the :ignore: tag:
;; Used to not export headings with :ignore: tag (after! org (require 'ox-extra) (ox-extras-activate '(ignore-headlines)))
HTML Export
HTML Defaults
(after! org ;; (setq org-html-head-extra (concat ;; "<link rel='stylesheet' href='../css/htmlize.css'>\n" ;; "<link rel='stylesheet' href='../css/readtheorg.css'>\n" ;; "<link rel='stylesheet' href='../css/zenburn.css'>\n" ;; "<link rel='text/javascript' href='../js/bootstrap.min.js'>\n" ;; "<link rel='text/javascript' href='../js/jquery.min.js'>\n" ;; "<link rel='text/javascript' href='../js/jquery.stickytableheaders.min.js'>\n" ;; "<link rel='text/javascript' href='../js/readtheorg.js'>\n")) ;; cleans up anything that would have been in there. (setq org-html-head nil) (setq org-html-head-include-default-style nil) (setq org-html-head-include-scripts nil) (setq org-html-viewport nil) (setq org-html-html5-fancy t) (setq org-html-doctype "xhtml-strict") (setq org-html-wrap-src-lines nil) ;; Export with css class instead of inline css (setq org-html-htmlize-output-type 'nil) )
MathJax
(after! org
  (setq org-html-mathjax-template
        "<script>MathJax = {
          tex: {
            tags: 'ams',
            macros: {bm: [\"\\\\boldsymbol{#1}\",1],}
            }
          };
          </script>
          <script type=\"text/javascript\" src=\"%PATH\"></script>")
  (setq org-html-mathjax-options
        '((path "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js")
          (scale "100")
          (align "center")
          (font "TeX")
          (linebreaks "false")
          (autonumber "AMS")
          (indent "0em")
          (multlinewidth "85%")
          (tagindent ".8em")
          (tagside "right")))
  )
Ensuring useful HTML Anchors
[ ]https://github.com/alhassy/emacs.d[ ]https://github.com/alphapapa/unpackaged.el#export-to-html-with-useful-anchors
This is not working
(define-minor-mode unpackaged/org-export-html-with-useful-ids-mode
  "Attempt to export Org as HTML with useful link IDs.
Instead of random IDs like \"#orga1b2c3\", use heading titles,
made unique when necessary."
  :global t
  (if unpackaged/org-export-html-with-useful-ids-mode
      (advice-add #'org-export-get-reference :override #'unpackaged/org-export-get-reference)
    (advice-remove #'org-export-get-reference #'unpackaged/org-export-get-reference)))
(defun unpackaged/org-export-get-reference (datum info)
  "Like `org-export-get-reference', except uses heading titles instead of random numbers."
  (let ((cache (plist-get info :internal-references)))
    (or (car (rassq datum cache))
        (let* ((crossrefs (plist-get info :crossrefs))
               (cells (org-export-search-cells datum))
               ;; Preserve any pre-existing association between
               ;; a search cell and a reference, i.e., when some
               ;; previously published document referenced a location
               ;; within current file (see
               ;; `org-publish-resolve-external-link').
               ;;
               ;; However, there is no guarantee that search cells are
               ;; unique, e.g., there might be duplicate custom ID or
               ;; two headings with the same title in the file.
               ;;
               ;; As a consequence, before re-using any reference to
               ;; an element or object, we check that it doesn't refer
               ;; to a previous element or object.
               (new (or (cl-some
                         (lambda (cell)
                           (let ((stored (cdr (assoc cell crossrefs))))
                             (when stored
                               (let ((old (org-export-format-reference stored)))
                                 (and (not (assoc old cache)) stored)))))
                         cells)
                        (when (org-element-property :raw-value datum)
                          ;; Heading with a title
                          (unpackaged/org-export-new-title-reference datum cache))
                        ;; NOTE: This probably breaks some Org Export
                        ;; feature, but if it does what I need, fine.
                        (org-export-format-reference
                         (org-export-new-reference cache))))
               (reference-string new))
          ;; Cache contains both data already associated to
          ;; a reference and in-use internal references, so as to make
          ;; unique references.
          (dolist (cell cells) (push (cons cell new) cache))
          ;; Retain a direct association between reference string and
          ;; DATUM since (1) not every object or element can be given
          ;; a search cell (2) it permits quick lookup.
          (push (cons reference-string datum) cache)
          (plist-put info :internal-references cache)
          reference-string))))
(defun unpackaged/org-export-new-title-reference (datum cache)
  "Return new reference for DATUM that is unique in CACHE."
  (cl-macrolet ((inc-suffixf (place)
                             `(progn
                                (string-match (rx bos
                                                  (minimal-match (group (1+ anything)))
                                                  (optional "--" (group (1+ digit)))
                                                  eos)
                                              ,place)
                                ;; HACK: `s1' instead of a gensym.
                                (-let* (((s1 suffix) (list (match-string 1 ,place)
                                                           (match-string 2 ,place)))
                                        (suffix (if suffix
                                                    (string-to-number suffix)
                                                  0)))
                                  (setf ,place (format "%s--%s" s1 (cl-incf suffix)))))))
    (let* ((title (org-element-property :raw-value datum))
           (ref (url-hexify-string (substring-no-properties title)))
           (parent (org-element-property :parent datum)))
      (while (--any (equal ref (car it))
                    cache)
        ;; Title not unique: make it so.
        (if parent
            ;; Append ancestor title.
            (setf title (concat (org-element-property :raw-value parent)
                                "--" title)
                  ref (url-hexify-string (substring-no-properties title))
                  parent (org-element-property :parent parent))
          ;; No more ancestors: add and increment a number.
          (inc-suffixf ref)))
      ref)))
Folded Drawers
Adapt this from https://github.com/alhassy/emacs.d to do something similar for source blocks.
(defun my/org-drawer-format (name contents)
  "Export to HTML the drawers named with prefix ‘fold_’, ignoring case.
The resulting drawer is a ‘code-details’ and so appears folded;
the user clicks it to see the information therein.
Henceforth, these are called ‘fold drawers’.
Drawers without such a prefix may be nonetheless exported if their
body contains ‘:export: t’ ---this switch does not appear in the output.
Thus, we are biased to generally not exporting non-fold drawers.
One may suspend export of fold drawers by having ‘:export: nil’
in their body definition.
Fold drawers naturally come with a title.
Either it is specfied in the drawer body by ‘:title: ⋯’,
or otherwise the drawer's name is used with all underscores replaced
by spaces.
"
  (let* ((contents′ (replace-regexp-in-string ":export:.*\n?" "" contents))
         (fold? (s-prefix? "fold_" name 'ignore-case))
         (export? (string-match ":export:\s+t" contents))
         (not-export? (string-match ":export:\s+nil" contents))
         (title′ (and (string-match ":title:\\(.*\\)\n" contents)
                      (match-string 1 contents))))
    ;; Ensure we have a title.
    (unless title′ (setq title′ (s-join " " (cdr (s-split "_" name)))))
    ;; Output
    (cond
     ((and export? (not fold?)) contents′)
     (not-export? nil)
     (fold?
      (thread-last contents′
        (replace-regexp-in-string ":title:.*\n" "")
        (format "<details class=\"code-details\"> <summary> <strong>
            <font face=\"Courier\" size=\"3\" color=\"green\"> %s
            </font> </strong> </summary> %s </details>" title′))))))
(setq org-html-format-drawer-function 'my/org-drawer-format)
Org LaTeX
LaTeX Fragments
(after! org
  ;; Highligh latex parts in org mode
  (setq org-highlight-latex-and-related '(latex script entities))
  ;; Use F9 to globally generate all the latex fragments
  (map! :map org-mode-map
        :n "<f9>"
        (lambda () (interactive) (org-preview-latex-fragment 16)))
  ;; Put all the preview images in some directory
  (setq org-preview-latex-image-directory "~/.ltximg/")
  ;; Define backends to preview LaTeX fragments
  (setq org-preview-latex-process-alist '((imagemagick
                                           :programs ("pdflatex" "convert")
                                           :description "pdf > png"
                                           :message "you need to install the programs: pdflatex and imagemagick."
                                           :image-input-type "pdf"
                                           :image-output-type "png"
                                           :image-size-adjust (1.0 . 1.0)
                                           :latex-compiler ("pdflatex -interaction nonstopmode -output-directory %o %f")
                                           :image-converter ("convert -density %D -trim -antialias %f -quality 100 %O"))
                                          (dvipng
                                           :programs ("latex" "dvipng")
                                           :description "dvi > png"
                                           :message "you need to install the programs: latex and dvipng."
                                           :image-input-type "dvi"
                                           :image-output-type "png"
                                           :image-size-adjust (0.4 . 0.4)
                                           :latex-compiler ("latex -interaction nonstopmode -output-directory %o %f")
                                           :image-converter ("dvipng -D %D -T tight -o %O %f"))
                                          (dvisvgm
                                           :programs ("pdflatex" "dvisvgm")
                                           :description "dvi > svg"
                                           :message "you need to install the programs: latex and dvisvgm."
                                           :image-input-type "dvi"
                                           :image-output-type "svg"
                                           :image-size-adjust (0.6 . 0.6)
                                           :latex-compiler ("latex -interaction nonstopmode -output-directory %o %f")
                                           :image-converter ("dvisvgm %f -n -b min -c %S -o %O"))
                                          ))
  ;; Use imagemagick/dvisvgm to generate png from pdf
  (setq org-preview-latex-default-process 'dvisvgm)
  ;; Don't change the font size for subscripts and superscripts in latex fragments.
  ;; This cause the orgmode tables not to be well aligned.
  (setq font-latex-fontify-script nil)
  ;; Colors of latex fragments
  (setq org-format-latex-options (plist-put org-format-latex-options :foreground 'default))
  (setq org-format-latex-options (plist-put org-format-latex-options :background (face-background 'fringe)))
  )
LaTeX Classes
(after! org
;; Custom classes to use when exporting to latex
(add-to-list 'org-latex-classes
          '("beamer"
            ,(concat "\\documentclass[presentation]{beamer}\n"
                     "[DEFAULT-PACKAGES]"
                     "[PACKAGES]"
                     "[EXTRA]\n")
            ("\\section{%s}" . "\\section*{%s}")
            ("\\subsection{%s}" . "\\subsection*{%s}")
            ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
(add-to-list 'org-latex-classes
             '("clean-cheatsheet"
               "\\documentclass{clean-cheatsheet}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
             )
(add-to-list 'org-latex-classes
             '("clean-beamer"
               "\\documentclass{clean-beamer}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
             )
(add-to-list 'org-latex-classes
             '("cleanreport"
               "\\documentclass{cleanreport}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
             )
(add-to-list 'org-latex-classes
             '("scrreprt"
               "\\documentclass{scrreprt}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
             )
(add-to-list 'org-latex-classes
             '("biblioreport"
               "\\documentclass{biblioreport}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
             )
)
Ox Latex Subfigure package
(use-package! ox-latex-subfigure :after org :config (require 'ox-latex-subfigure))
Clear page before heading
https://emacs.stackexchange.com/questions/30575/adding-latex-newpage-before-a-heading/30892
(after! org
  (defun tdh-get-headline-string-element  (headline backend info)
    (let ((prop-point (next-property-change 0 headline)))
      (if prop-point (plist-get (text-properties-at prop-point headline) :parent))))
  (defun tdh-ensure-latex-clearpage (headline backend info)
    (when (org-export-derived-backend-p backend 'latex)
      (let ((elmnt (tdh-get-headline-string-element headline backend info)))
        (when (and elmnt (org-element-property :CLEARPAGE elmnt))
          (concat "\\clearpage\n" headline)))))
  (add-to-list 'org-export-filter-headline-functions
               'tdh-ensure-latex-clearpage)
  )
Default added packages
(after! org
  (add-to-list 'org-latex-packages-alist '("" "siunitx" t))
  (add-to-list 'org-latex-packages-alist '("" "array" t))
  (add-to-list 'org-latex-packages-alist '("" "tabularx" t))
  (add-to-list 'org-latex-packages-alist '("" "booktabs" t))
  (add-to-list 'org-latex-packages-alist '("" "bm" t))
  (add-to-list 'org-latex-packages-alist '("most" "tcolorbox" t))
  )
Some configurations
(after! org
  ;; Setup default option for image size when exporting to LaTeX
  (setq org-latex-image-default-scale "")
  (setq org-latex-image-default-width "\\linewidth")
  (setq org-latex-image-default-height "")
  (setq org-latex-image-default-option "")
  ;; Use define labels instead of automatic generated ones
  (setq org-latex-prefer-user-labels t)
  ;; Captions above the table
  (setq org-latex-caption-above '(table))
  ;; Settings to export code with `minted' instead of `verbatim'.
  (setq org-latex-listings 'minted)
  ;; Set the following as images
  (setq org-latex-inline-image-rules '(("file" . "\\.\\(pdf\\|jpeg\\|jpg\\|png\\|ps\\|eps\\|tikz\\|pgf\\|svg\\|gif\\)\\'")))
  ;; Command used when exporting to pdf
  (setq org-latex-pdf-process
        '("latexmk -cd -pdflatex=\"pdflatex -synctex=1 -shell-escape -interaction nonstopmode -output-directory %o\" -pdf -bibtex -f %f"))
  )
Beamer
Bold Text
(after! org
  (defun tdh-my-beamer-bold (contents backend info)
    (when (eq backend 'beamer)
      (replace-regexp-in-string
       (concat "\\`\\\\" "[A-Za-z0-9]+") ;; If not, orgmode is crazy...
       "\\\\textbf"
       contents)))
  (add-to-list 'org-export-filter-bold-functions 'tdh-my-beamer-bold)
  )
Special Environments
[ ]Make some comment those special environments
(after! org
  (add-to-list 'org-beamer-environments-extra
               '("cbox" ;; Name of environment
                 "m" ;; Selection key
                 "\\onslide%a{\\begin{cbox}[%h]%O"
                 "\\end{cbox}}\\vspace{0.5em}"))
  (add-to-list 'org-beamer-environments-extra
               '("csubbox" ;; Name of environment
                 "M" ;; Selection key
                 "\\onslide%a{\\tcbsubtitle{%h}"
                 "}"))
  )
Custom Export - Add Page and Label for LaTeX export
(defcustom tdh-org-property-mapping
  '((latex ("CUSTOM_PAGE" . tdh-insert-org-page-latex)
           ("CUSTOM_LABEL" . tdh-insert-org-label-latex)))
  "List of mappings from org property to arbitrary strings.
Each element is a list:
  (BACKEND (PROPERTY1 . FUNCTION1) (PROPERTY2 . FUNCTION2) ...)
FUNCTION are functions which get called with a single
argument (the value of PROPERTY) and are responsible for doing
whatever should be done."
  :type '(repeat (cons symbol (repeat (cons string string)))))
(defun tdh-replace-org-property (backend)
  "Convert org properties using `tdh-org-property-mapping'.
Lookup BACKEND in `tdh-org-property-mapping' for a list of
(PROPERTY REPLACEMENT). For each healine being exported, if it has a
PROPERTY listed insert a string immediately after the healine given by
    (format REPLACEMENT PROPERTY-VALUE)"
  (let ((map (cdr (assoc backend tdh-org-property-mapping)))
        value replacement)
    (when map
      (org-map-entries
       (lambda ()
         (dolist (it map)
           (save-excursion
             (when (setq value (org-entry-get (point) (car it)))
               (funcall (cdr it) value)))))))))
(add-hook 'org-export-before-processing-hook #'tdh-replace-org-property)
(defun tdh-insert-org-label-latex (label)
  "Insert \"\\\\label{LABEL}\\n\" after the :PROPERTY: drawer."
  (search-forward-regexp org-property-end-re)
  (forward-char 1)
  (insert (format "\\label{%s}\n" label)))
(defun tdh-insert-org-page-latex (page)
  "Insert \"\\\\page{PAGE}\\n\" after the :PROPERTY: drawer."
  (search-forward-regexp org-property-end-re)
  (forward-char 1)
  (insert (format "\\page{%s}\n" page)))
Number Equations
(after! org
  (defun tdh-org-renumber-environment (orig-func &rest args)
    "A function to inject numbers in LaTeX fragment previews."
    (let ((results '())
          (counter -1)
          (numberp))
      (setq results (loop for (begin .  env) in
                          (org-element-map (org-element-parse-buffer) 'latex-environment
                            (lambda (env)
                              (cons
                               (org-element-property :begin env)
                               (org-element-property :value env))))
                          collect
                          (cond
                           ((and (string-match "\\\\begin{equation}" env)
                                 (not (string-match "\\\\tag{" env)))
                            (incf counter)
                            (cons begin counter))
                           ((string-match "\\\\begin{align}" env)
                            (prog2
                                (incf counter)
                                (cons begin counter)
                              (with-temp-buffer
                                (insert env)
                                (goto-char (point-min))
                                ;; \\ is used for a new line. Each one leads to a number
                                (incf counter (count-matches "\\\\$"))
                                ;; unless there are nonumbers.
                                (goto-char (point-min))
                                (decf counter (count-matches "\\nonumber")))))
                           (t
                            (cons begin nil)))))
      (when (setq numberp (cdr (assoc (point) results)))
        (setf (car args)
              (concat
               (format "\\setcounter{equation}{%s}\n" numberp)
               (car args)))))
    (apply orig-func args))
  (advice-add 'org-create-formula-image :around #'tdh-org-renumber-environment)
  )
LaTeX macro both for LaTeX and HTML export
https://www.reddit.com/r/orgmode/comments/7u2n0h/tip_for_defining_latex_macros_for_use_in_both/
(after! org
  (add-to-list 'org-src-lang-modes '("latex-macros" . latex))
  (defvar org-babel-default-header-args:latex-macros
    '((:results . "raw")
      (:exports . "results")))
  (defun prefix-all-lines (pre body)
    (with-temp-buffer
      (insert body)
      (string-insert-rectangle (point-min) (point-max) pre)
      (buffer-string)))
  (defun org-babel-execute:latex-macros (body _params)
    (concat
     "\n#+begin_export html\n<div style=\"display: none\"> \\(\n"
     body
     "\n\\)</div>\n#+end_export\n"))
  )
Org Projects
(setq org-publish-project-alist
      '(("config"
         :base-directory "~/.config/literate-dotfiles/dotfiles/"
         :publishing-directory "~/.config/literate-dotfiles/docs/"
         :recursive nil
         :publishing-function org-html-publish-to-html
         :auto-sitemap nil
         :section-numbers nil
         :table-of-contents nil)
        ("stewart-simscape"
         :base-directory "~/Cloud/thesis/matlab/stewart-simscape/org/"
         :base-extension "org"
         :publishing-directory "~/Cloud/thesis/matlab/stewart-simscape/docs/"
         :author "Dehaeze Thomas"
         :email "dehaeze.thomas@gmail.com/"
         :recursive nil
         :publishing-function org-html-publish-to-html
         :auto-preamble t
         :auto-sitemap nil
         :html-link-up "index.html"
         :html-link-home "index.html"
         :with-todo-keywords nil
         :html-wrap-src-lines nil
         :table-of-contents nil)
        ("nass-simscape"
         :base-directory "~/Cloud/thesis/matlab/nass-simscape/org/"
         :base-extension "org"
         :publishing-directory "~/Cloud/thesis/matlab/nass-simscape/docs/"
         :author "Dehaeze Thomas"
         :email "dehaeze.thomas@gmail.com/"
         :recursive nil
         :publishing-function org-html-publish-to-html
         :auto-preamble t
         :auto-sitemap nil
         :html-link-up "index.html"
         :html-link-home "index.html"
         :with-todo-keywords nil
         :html-wrap-src-lines nil
         :table-of-contents nil)
        ("tikz-maker"
         :base-directory "~/Cloud/tikz/org/"
         :base-extension "org"
         :publishing-directory "~/Cloud/tikz/docs/"
         :author "Dehaeze Thomas"
         :email "dehaeze.thomas@gmail.com/"
         :recursive nil
         :publishing-function org-html-publish-to-html
         :auto-preamble t
         :auto-sitemap nil
         :html-link-up "index.html"
         :html-link-home "index.html"
         :with-todo-keywords nil
         :html-wrap-src-lines nil
         :table-of-contents nil)))
Org big org-project
(setq org-publish-project-alist
      '(("website"
         :components ("nass-simscape" "nass-simscape-images"))
        ("nass-simscape"
         :base-directory "~/Cloud/thesis/matlab/nass-simscape/org/"
         :base-extension "org"
         :publishing-directory "~/Cloud/website/nass-simscape/"
         :publishing-function org-html-publish-to-html
         :html-link-up "./index.html"
         :html-link-home "~/Cloud/website/index.html"
         :html-footnotes-section "<div id='footnotes'><!--%s-->%s</div>"
         :recursive nil
         :auto-sitemap nil
         :language en)
        ("nass-simscape-images"
         :base-directory "~/Cloud/thesis/matlab/nass-simscape/docs/figs/"
         :base-extension "png"
         :publishing-directory "~/Cloud/website/nass-simscape/figs/"
         :publishing-function org-publish-attachment)
        ))
Automatically run startblock when opening org-mode files
(after! org
  (defun tdh-eval-startblock ()
    (if (member "startblock" (org-babel-src-block-names))
        (save-excursion
          (org-babel-goto-named-src-block "startblock")
          (org-babel-execute-src-block))
      nil
      )
    )
  (add-hook 'org-mode-hook 'tdh-eval-startblock)
  )
Insert ScreenShot or Picture from Phone
http://pragmaticemacs.com/emacs/a-workflow-to-quickly-add-photos-to-org-mode-notes/
[ ]One function to move file from~/Picture/folder (where the screenshots are taken) to current directory and then insert and org link to the picture. Maybe ask if it should be copied in a sub directory (figs folder for instance).[ ]One function to copy file from~/Cloud/Photos/folder (where the pictures from phone are taken) to current directory (and ask for the new name of the picture) and insert org link.
;; required libraries
(require 'dash)
;; (require 'swiper)
(require 's)
;; start directory
(defvar tdh-image-dir (expand-file-name "/home/thomas/Pictures"))
(defun tdh-insert-conference-image ()
  "Insert image from conference directory, rename and add link in current file.
The file is taken from a start directory set by `tdh-image-dir' and moved to the current directory, renamed and embedded at the point as an org-mode link. The user is presented with a list of files in the start directory, from which to select the file to move, sorted by most recent first."
  (interactive)
  (let (file-list target-dir file-list-sorted start-file start-file-full file-ext end-file end-file-base end-file-full file-number)
    ;; Clean directories from list but keep times
    (setq file-list
          (-remove (lambda (x) (nth 1 x))
                   (directory-files-and-attributes tdh-image-dir)))
    ;; Get target directory
    (setq target-dir (file-name-directory (buffer-file-name)))
    ;; Sort list by most recent
    (setq file-list-sorted
          (mapcar #'car
                  (sort file-list
                        #'(lambda (x y) (time-less-p (nth 6 y) (nth 6 x))))))
    ;; Use ivy to select start-file
    (setq start-file (ivy-read
                      (concat "Move selected file to " target-dir ":")
                      file-list-sorted
                      :re-builder #'ivy--regex
                      :sort nil
                      :initial-input nil))
    ;; add full path to start file and end-file
    (setq start-file-full
          (expand-file-name start-file tdh-image-dir))
    ;; final file name including path
    (setq end-file-full
          (expand-file-name start-file target-dir))
    ;; rename file
    (rename-file start-file-full end-file-full)
    (message "moved %s to %s" start-file-full start-file)
    ;; insert link
    (insert (org-make-link-string (format "file:%s" start-file)))
    ;; display image
    (org-display-inline-images t t)))
Render Tables
https://www.reddit.com/r/emacs/comments/d3a8or/pretty_org_tables_in_the_buffer_chapter_2_it/
(after! org
  (defun tdh-render-org-table-at-point ()
    (interactive)
    (save-excursion
      (beginning-of-line)
      ;; removes the overlay is already there
      (if (overlays-at (point))
          (delete-overlay (car (overlays-at (point))))
        (let* ((element-type (org-element-type (org-element-at-point))))
          (if (and (not (eq element-type 'table))
                   (not (eq element-type 'table-row)))
              (error "not at an org table")
            (while (not (eq 'table (org-element-type (org-element-at-point))))
              (forward-line -1))
            (tdh-render-org-table (org-element-at-point))
            )))))
  (defun tdh-render-org-table (table)
    (interactive)
    (let* ((begin (org-element-property :begin table))
           (end (let ((pos (org-element-property :end table)))
                  (goto-char pos)
                  (beginning-of-line)
                  ;; skip possible space after table
                  (while (not (looking-at " *[|#]"))
                    (setq pos (point))
                    (forward-line -1))
                  pos))
           (tabletxt (buffer-substring-no-properties begin end))
           (img (with-temp-buffer
                  (insert tabletxt)
                  (mark-whole-buffer)
                  (org-latex-convert-region-to-latex)
                  (org-latex-preview)
                  (goto-char (point-min))
                  (overlay-get  (car (overlays-at (point))) 'display)))
           (overlay (make-overlay begin end)))
      (overlay-put overlay 'display img)
      (forward-line -1))
    )
  (defun tdh-render-org-tables-in-buffer ()
    (save-excursion
      (org-element-map (org-element-parse-buffer) 'table 'tdh-render-org-table)))
  ;; Use F9 to globally generate tables
  (map! :map org-mode-map :n "<f8>" (lambda () (interactive) (tdh-render-org-table-at-point)))
  )
Org Gcal
(use-package! org-gcal
  :after org
  :init
  :config
  (setq org-gcal-client-id "396102378658-dcmbcmrnthbe925519otsjbd921otq0v.apps.googleusercontent.com"
        org-gcal-client-secret "4M5PWrbhQjwYEMXGK85lDYX9"
        org-gcal-file-alist '(("dehaeze.thomas@gmail.com" . "~/Cloud/org/gcal.org")
                              ("8kjmhe2ar0abnm054ill1fb0gc@group.calendar.google.com" . "~/Cloud/org/gcal_phd.org")))
  ;; Automatic fetch of the new events
  ;; (add-hook 'org-agenda-mode-hook (lambda () (org-gcal-fetch) ))
)
Custom Keybindings - , leader key and C-c
C-c a | 
Org Agenda | 
C-c n | 
Narrow to Subtree | 
C-c l | 
Org Link | 
(after! org
  (map! :map org-mode-map
   (:desc "Org Agenda"
     :ni "C-c a" 'org-agenda)
   (:desc "Archive"
     :n "C-c A" 'org-archive-subtree)
   (:desc "Org Capture"
     :ni "C-c c" 'org-capture)
   (:desc "Store Link"
     :ni "C-c l" 'org-store-link)
   (:desc "Narrow Subtree"
     :ni "C-c n" 'org-toggle-narrow-to-subtree)
   (:desc "Org Noter"
     :ni "C-c N" 'org-noter)
   (:desc "Align Block"
     :ni "C-c =" 'tdh-align-src-block)
   (:desc "Insert Reference"
     :ni "C-c r" 'org-ref-insert-ref-link)
   (:desc "Insert Image"
     :ni "C-c i" 'tdh-insert-image-org-link)
   (:desc "Insert Image SXIV"
     :ni "C-c I" 'tdh-insert-image-org-link-sxiv)
   (:desc "Link to next Figure"
     :ni "C-c f" 'tdh-insert-link-to-next-figure)
   (:desc "Link to previous Figure"
     :ni "C-c F" 'tdh-insert-link-to-previous-figure)
   (:desc "Insert Screenshot"
     :ni "C-c s" 'tdh-insert-screenshot-org-link)
   (:desc "Find Roam"
     :ni "C-c r" 'orb-find-non-ref-file)
   (:desc "Insert Roam"
     :ni "C-c R" 'orb-insert-non-ref)
   ))
Insert Elements ,i
Insert Link to paper
(defun tdh-insert-paper-org-link (paper) "Insert an org link to some paper, choosing the file with completion" (interactive (list (read-file-name "Paper: " "~/Cloud/pdfs/" nil t))) (insert (format "[[papers:%s]]" (file-name-base paper))))
Insert Link to notes
(defun tdh-insert-note-org-link (note) "Insert an org link to some note, choosing the file with completion" (interactive (list (read-file-name "Note: " "~/Cloud/pdfs/" nil t))) (insert (format "[[notes:%s]]" (file-name-base note))))
Insert Image that is in the figs folder
(defun tdh-insert-image-org-link (img) "Insert an org image link, choosing the file with completion and starting from `my-default-image-directory'." (interactive (list (file-relative-name (read-file-name "Image: " (concat default-directory "figs/")) default-directory))) (insert (format "[[file:%s]]" img)))
Insert Image that is in the figs folder using SXIV
(defun tdh-insert-image-org-link-sxiv ()
  "Insert an org image link, choosing the file with completion
and starting from `my-default-image-directory'."
  (interactive)
  (setq img (shell-command-to-string "ls figs/*.{jpg,jpeg,bmp,png,gif} 2> /dev/null | sxiv -i -t -o | tail -1 | tr -d '\n'"))
  (unless (equal "" img)
    (insert (format "[[file:%s]]" img)))
  )
Copy picture from phone folder using SXIV and insert it
(defun tdh-insert-phone-picture ()
  (interactive)
  (setq img (shell-command-to-string "~/.config/doom/bin/copy-phone-picture.sh"))
  (unless (equal "" img)
    (insert (format "[[file:%s]]" img)))
  )
Bash script for copying pictures taken by phone.
if [ -z "$1" ]; then
    oldpath=$(ls -t ~/Cloud/photos/phone/*.jpg | sxiv -i -t -o | tail -1);
else
    oldpath=$(ls -t $1 | sxiv -i -t -o | tail -1);
fi
if [ -n "$oldpath" ]; then
    newfilename=$(basename $oldpath .jpg | rofi -i -dmenu -p "Filename")
    if [ -n "$newfilename" ]; then
        cp $oldpath "figs/$newfilename.jpg"
        printf "figs/$newfilename.jpg"
    fi
fi
Take Screenshot and insert a link:
- Ask for a name 
screenshot_name - use 
maim -s figs/screenshot_name.pngto take a screenshot with selection - Then insert the following to the buffer
 
(defun tdh-insert-screenshot-org-link ()
  "Capture screenshot and insert the resulting file.
The screenshot tool is determined by `org-download-screenshot-method'."
  (interactive)
  (if (string-match "_" (file-name-base buffer-file-name))
      (setq filename (read-string "Enter file name:" (car (split-string (file-name-base buffer-file-name) "_"))))
    (setq filename (read-string "Enter file name:")))
  (setq filepath (concat "./figs/" filename ".png"))
  (shell-command (concat "maim -s " filepath))
  (insert (format "#+name: fig:%s\n#+caption:\n[[file:%s]]" filename filepath))
  (search-backward "caption")
  (end-of-line)
  )
Insert link to next figure:
(defun tdh-insert-link-to-next-figure ()
  (interactive)
  (save-excursion
    (re-search-forward "^#\\+name:\s*\\(fig:.*\\)" nil t 1))
  (insert (concat "[[" (match-string 1) "]]"))
  )
Insert link to previous figure:
(defun tdh-insert-link-to-previous-figure ()
  (interactive)
  (save-excursion
    (re-search-backward "^#\\+name:\s*\\(fig:.*\\)" nil t 1))
  (insert (concat "[[" (match-string 1) "]]"))
  )
Map Keys
(after! org
  (map! :map org-mode-map
        (:prefix (",i" . "Insert")
        :n "p" 'tdh-insert-paper-org-link
        :n "n" 'tdh-insert-note-org-link
        :n "f" 'tdh-insert-image-org-link
        :n "F" 'tdh-insert-image-org-link-sxiv
        :n "i" 'tdh-insert-phone-picture
        :n "l" 'tdh-insert-link-to-next-figure
        :n "L" 'tdh-insert-link-to-previous-figure
        :n "s" 'tdh-insert-screenshot-org-link)))
LaTeX ,l
(defun tdh-latex-watch ()
  "Watch LaTeX file using latexmk"
  (interactive)
  (start-process-shell-command "latexmk-watch" "*latexmk-watch-output*"
                               "latexmk" (format "-pdflatex=\"xelatex -synctex=1 -shell-escape -interaction nonstopmode  -output-directory='%s'\" -pdf -pvc -bibtex -f %s.tex"
                                                 (file-name-directory buffer-file-name)
                                                 (file-name-base buffer-file-name))))
(defun tdh-latex-watch-kill () "Kill the currently running TeX job." (interactive) (delete-process "latexmk-watch") )
(after! org
  (map! :map org-mode-map
        (:prefix (",l" . "LaTeX")
        :n "w" 'tdh-latex-watch
        :n "k" 'tdh-latex-watch-kill
        :n "l" 'org-latex-export-to-latex)))
Org LaTeX Automatic fragment
(defun tdh-automatic-latex-fragment-activate () (interactive) (add-hook 'org-mode-hook 'org-fragtog-mode)) (defun tdh-automatic-latex-fragment-deactivate () (interactive) (remove-hook 'org-mode-hook 'org-fragtog-mode))
(after! org
  (map! :map org-mode-map
        (:prefix (",l" . "LaTeX")
        :n "f" 'tdh-automatic-latex-fragment-activate
        :n "F" 'tdh-automatic-latex-fragment-deactivate)))
Bibtex ,r
(after! org
  (map! :map org-mode-map
        (:prefix (",r" . "References")
        :n "b" 'helm-bibtex
        :n "B" 'helm-bibtex-with-local-bibliography
        :n "f" 'tdh-helm-bibtex-favorites
        :n "r" 'helm-resume)))
Open ranger in current directory ,o
(defun tdh-open-ranger-in-workdir () (interactive) (call-process-shell-command (concat "termite --directory=" default-directory " --exec=ranger") nil 0))
(after! org
  (map! :map org-mode-map
        :n ",o" 'tdh-open-ranger-in-workdir))
View in External programs ,v
Open PDF output with zathura
(defun tdh-open-org-pdf-externally () (interactive) (call-process "zathura" nil 0 nil (concat (file-name-sans-extension (buffer-file-name)) ".pdf")) )
Open HTML output externally
(defun tdh-open-org-html-externally ()
    (interactive)
    (call-process "xdg-open" nil 0 nil (concat (file-name-sans-extension (buffer-file-name)) ".html"))
    )
(after! org
  (map! :map org-mode-map
        (:prefix (",v" . "View")
        :n "p" 'tdh-open-org-pdf-externally
        :n "h" 'tdh-open-org-html-externally)))
Org Babel
Main configuration
Don’t ask for confirmation when evaluating following blocs
(defun tdh-org-confirm-babel-evaluate (lang body)
  (not (member lang '("emacs-lisp" "latex" "matlab" "sh" "latex-macros" "python"))))
(after! org
  (setq org-confirm-babel-evaluate 'tdh-org-confirm-babel-evaluate))
Default header arguments.
(after! org (setq org-babel-default-header-args '((:eval . "no-export"))))
Use the current window for C-c ’ source editing
(after! org (setq org-src-window-setup 'current-window))
Appearance of source blocks
(defun tdh-org-prettify-symbols ()
  (mapc (apply-partially 'add-to-list 'prettify-symbols-alist)
        (cl-reduce 'append
                   (mapcar (lambda (x) (list x (cons (upcase (car x)) (cdr x))))
                           `(("#+begin_src" . ?✎)
                             ("#+end_src"   . ?□)
                             ("#+begin_quote" . ?«)
                             ("#+end_quote" . ?»)))))
  (turn-on-prettify-symbols-mode))
(add-hook 'org-mode-hook #'tdh-org-prettify-symbols)
Indentation
(after! org
  (setq org-edit-src-content-indentation 2
        org-src-tab-acts-natively nil
        org-src-preserve-indentation nil)
  )
Library of Babel
Add all named source blocks to org-babel-library-of-babel (link).
(after! org (org-babel-lob-ingest "~/.config/literate-dotfiles/dotfiles/emacs-library-babel.org"))
Org-Babel Matlab
(after! org
  (setq org-babel-matlab-shell-command "/home/thomas/.local/bin/matlab -softwareopengl -nodesktop -nosplash")
  (setq org-babel-matlab-emacs-link-wrapper-method
        "%s
      if ischar(ans);
      echo('test');
      fid = fopen('%s', 'w');
      fprintf(fid, '%s', ans);
      fclose(fid);
      else;
      save -ascii %s ans;
      end
      delete('%s');
      ")
  )
Default options for Matlab code
(after! org
  (setq org-babel-default-header-args:matlab
        '((:results . "none")
          (:session . "*MATLAB*")
          (:comments . "org")
          (:exports . "both")
          (:cache .   "no")
          (:noweb . "no")
          (:hlines . "no")
          (:tangle . "yes")
          (:mkdir . "yes")
          (:eval . "no-export")))
  )
Some functions for using Matlab with Org Babel ,m
whos matlab function
(defun tdh-matlab-whos (&optional start end)
"Get what is in the Matlab workspace"
  (interactive)
  (if (use-region-p)
    (let ((regionp (buffer-substring (region-beginning) (region-end))))
      (process-send-string "*MATLAB*" (concat "whosEmacs " regionp "\n")))
    (process-send-string "*MATLAB*" (concat "whosEmacs" "\n"))))
help matlab function
(defun tdh-matlab-help (&optional start end)
  "Get help on the selected function"
  (interactive)
  (if (use-region-p)
    (let ((regionp (buffer-substring (region-beginning) (region-end))))
        (process-send-string "*MATLAB*" (concat "help " regionp "\n")))
    (process-send-string "*MATLAB*" (concat "help " (read-string "Matlab help:") "\n")))
  )
Specify a Matlab command to run
(defun tdh-matlab-run-command () "Prompt user to enter a matlab command" (interactive) (process-send-string "*MATLAB*" (concat (read-string "Matlab Command: ") "\n")))
Specify a Matlab command to run and show output in mini-buffer
(defun tdh-matlab-run-command-show-output ()
  "Prompt user to enter a matlab command"
  (interactive)
  (process-send-string "*MATLAB*" (concat "evalEmacs('" (read-string "Matlab Command: ") "')\n")))
Org-Babel Tangle File and Execute with Matlab
(defun tdh-matlab-tangle-and-execute ()
  "Jump to tangle file for the source block at point."
  (interactive)
  (let (file org-babel-pre-tangle-hook org-babel-post-tangle-hook)
    (cl-letf (((symbol-function 'write-region) (lambda (start end filename &rest _ignore)
                         (setq file filename)))
          ((symbol-function 'delete-file) #'ignore))
      (org-babel-tangle '(4)))
    (when file
      (setq file (expand-file-name file))
      (if (file-readable-p file)
      (process-send-string "*MATLAB*" (concat "run " file "\n"))
    (error "Cannot open tangle file %S" file)))))
Map Functions
(after! org
  (map! :map org-mode-map
        (:prefix (",m" . "Matlab")
        :n  "e" 'tdh-matlab-run-command
        :n  "E" 'tdh-matlab-run-command-show-output
        :n  "T" 'tdh-matlab-tangle-and-execute
        :nv "h" 'tdh-matlab-help
        :nv "w" 'tdh-matlab-whos)))
Remap ctrl-ret used to execute the src block and go to the next one
Remap ctrl-ret to execute the source block and go to the next source block
when inside a source block. Otherwise, keep the normal behavior for ctrl-ret.
(defun tdh-ctrl-ret ()
  (interactive)
  (defun tdh-in-src-block-p ()
    "Returns t when the point is inside a source code block"
    (string= "src" (org-in-block-p '("src"))))
  (if (tdh-in-src-block-p)
      (progn
        (org-babel-execute-src-block)
        (org-babel-next-src-block))
    (+org--insert-item 'below)))
(map! :after evil-org
      :map evil-org-mode-map
      :n "<C-return>" #'tdh-ctrl-ret)
Remap ctrl-shift-ret used to execute the (matlab) src block in the background and go to the next one
tdh-org-babel-execute-matlab-background
(defun tdh-org-babel-execute-matlab-background (&optional arg info params)
  (interactive)
  (let* ((org-babel-current-src-block-location
      (or org-babel-current-src-block-location
          (nth 5 info)
          (org-babel-where-is-src-block-head)))
     (info (if info (copy-tree info) (org-babel-get-src-block-info))))
    ;; Merge PARAMS with INFO before considering source block
    ;; evaluation since both could disagree.
    (cl-callf org-babel-merge-params (nth 2 info) params)
    (when (org-babel-check-evaluate info)
      (cl-callf org-babel-process-params (nth 2 info))
      (let* ((params (nth 2 info))
         (cache (let ((c (cdr (assq :cache params))))
              (and (not arg) c (string= "yes" c))))
         (new-hash (and cache (org-babel-sha1-hash info :eval)))
         (old-hash (and cache (org-babel-current-result-hash)))
         (current-cache (and new-hash (equal new-hash old-hash))))
    (cond
     (current-cache
      (save-excursion		;Return cached result.
        (goto-char (org-babel-where-is-src-block-result nil info))
        (forward-line)
        (skip-chars-forward " \t")
        (let ((result (org-babel-read-result)))
          (message (replace-regexp-in-string "%" "%%" (format "%S" result)))
          result)))
     ((org-babel-confirm-evaluate info)
      (let* ((lang (nth 0 info))
         (result-params (cdr (assq :result-params params)))
         ;; Expand noweb references in BODY and remove any
         ;; coderef.
         (body
          (let ((coderef (nth 6 info))
            (expand
             (if (org-babel-noweb-p params :eval)
                 (org-babel-expand-noweb-references info)
               (nth 1 info))))
            (if (not coderef) expand
              (replace-regexp-in-string
               (org-src-coderef-regexp coderef) "" expand nil nil 1))))
         (dir (cdr (assq :dir params)))
         (mkdirp (cdr (assq :mkdirp params)))
         (default-directory
           (cond
            ((not dir) default-directory)
            ((member mkdirp '("no" "nil" nil))
             (file-name-as-directory (expand-file-name dir)))
            (t
             (let ((d (file-name-as-directory (expand-file-name dir))))
               (make-directory d 'parents)
               d))))
         (cmd (intern (concat "org-babel-execute:" lang)))
         result)
        (process-send-string "*MATLAB*" (concat body "\n"))
        result))
     )))
    )
  )
tdh-matlab-execute-selected
(defun tdh-matlab-execute-selected (start end)
"Execute selected text in the *MATLAB* buffer"
  (interactive "r")
  (let ((regionp (buffer-substring start end)))
      (process-send-string "*MATLAB*" (concat regionp "\n"))))
Remap ctrl-shift-ref
This function:
- first check if inside a source block, if not does nothing
 - when check if the language is 
matlab- if it is not, it just runs the code and go to the next source block
 - if it is in a 
matlabblock, it first check if a region if selected, if so it just runs the selected region. if no region is selected, it runs all the code blocks and goes to the next block 
 
(defun tdh-ctrl-shift-ret ()
  (interactive)
  (defun tdh-in-src-block-p ()
    "Returns t when the point is inside a source code block"
    (string= "src" (org-in-block-p '("src"))))
  (if (tdh-in-src-block-p)
      (let ((lang (nth 0 (org-babel-get-src-block-info))))
        (if (string= lang "matlab")
            (if (region-active-p)
                (tdh-matlab-execute-selected (region-beginning) (region-end))
              (progn (tdh-org-babel-execute-matlab-background)
                     (org-babel-next-src-block)))
          (tdh-ctrl-ret))
        )
    )
  )
(map! :after evil-org
      :map evil-org-mode-map
      :n "<C-S-return>" #'tdh-ctrl-shift-ret)
Align Source Blocks
(defun tdh-align-src-block ()
  (interactive)
  (defun tdh-in-src-block-p ()
    "Returns t when the point is inside a source code block"
    (string= "src" (org-in-block-p '("src"))))
  (if (tdh-in-src-block-p)
      (progn
        (org-edit-special)
        (evil-indent (point-min) (point-max))
        (org-edit-src-exit))
    (org-table-eval-formula)))
Helping Functions - Tangling ,b
Org-Babel Tangle Sub-tree
(defun tdh-org-babel-tangle-subtree ()
  "Tangle the current subtree"
  (interactive)
  (progn
    (org-narrow-to-subtree)
    (org-babel-tangle)
    (widen))
  )
Org-Tangle and Org-Babel Jump to Tangle File
(defun tdh-org-babel-jump-to-tangle-file ()
  "Jump to tangle file for the source block at point."
  (interactive)
  (let (file org-babel-pre-tangle-hook org-babel-post-tangle-hook)
    (cl-letf (((symbol-function 'write-region) (lambda (start end filename &rest _ignore)
                                                 (setq file filename)))
              ((symbol-function 'delete-file) #'ignore))
      (org-babel-tangle '(4)))
    (when file
      (setq file (expand-file-name file))
      (if (file-readable-p file)
          (find-file file)
        (error "Cannot open tangle file %S" file)))))
Map Functions
(after! org
  (map! :map org-mode-map
        (:prefix (",b" . "Tangle")
        :n  "F" 'tdh-org-babel-jump-to-tangle-file
        :n  "T" 'tdh-org-babel-tangle-subtree)))
Bibliography Management
My bibliography management is mainly based on the following packages:
org-reffor nice citationsorg-noterto annotate documentsorg-roamto manage and links all my noteshelm-bibtexas an interface to easily find referencesorg-roam-bibtexthat connects all the above packages
Org Ref (link)
Nice Functions:
org-ref-insert-ref-linkorg-ref-helm-insert-cite-linkorg-ref-list-of-figuresorg-ref-find-bad-citationsorg-ref-clean-bibtex-entry
(use-package! org-ref
  :after org
  :init
  :config
  ;; Folder where the notes files are located (or file if just one Note file)
  (setq org-ref-notes-directory "~/Cloud/brain")
  (setq org-ref-bibliography-notes "~/Cloud/brain")
  ;; Bibliography File
  (setq reftex-default-bibliography  '("~/Cloud/brain/biblio/references.bib"))
  (setq org-ref-default-bibliography '("~/Cloud/brain/biblio/references.bib"))
  ;; Folder where all the pdf are located
  (setq org-ref-pdf-directory "~/Cloud/pdfs")
  ;; Tell org-ref to let helm-bibtex find notes for it
  (setq org-ref-notes-function
        (lambda (thekey)
          (let ((bibtex-completion-bibliography (org-ref-find-bibliography)))
            (bibtex-completion-edit-notes
             (list (car (org-ref-get-bibtex-key-and-file thekey)))))))
  ;; Problem with speed: don't display broken links
  (setq org-ref-show-broken-links t)
  ;; Display information on the citation
  (setq org-ref-show-citation-on-enter t)
  (add-to-list 'org-ref-helm-user-candidates
               '("Open pdf in Zathura" . (lambda () (call-process "zathura" nil 0 nil  (concat
                                                                                        (file-name-as-directory org-ref-pdf-directory)
                                                                                        (car (org-ref-get-bibtex-key-and-file))
                                                                                        ".pdf"))))
               t)
  (add-to-list 'org-ref-helm-user-candidates
               '("Drag and Drop" . (lambda () (call-process "/bin/bash" nil 0 nil "-c" (concat
                                                                                        "dragon-drag-and-drop "
                                                                                        (file-name-as-directory org-ref-pdf-directory)
                                                                                        (car (org-ref-get-bibtex-key-and-file))
                                                                                        ".pdf"))))
               t)
  ;; Let Mathjax deals with equation reference
  (defun org-ref-eqref-export (keyword desc format)
    (cond
     ((eq format 'latex) (format "\\eqref{%s}" keyword))
     ((eq format 'html) (format "\\eqref{%s}" keyword))
     ((eq format 'md) (format "\\eqref{%s}" keyword))))
  )
(defun tdh-org-ref-open-pdf-at-point ()
  "Open the pdf in external program for bibtex key under point if it exists."
  (interactive)
  (let* ((results (org-ref-get-bibtex-key-and-file))
         (key (car results))
         (pdf-file (funcall org-ref-get-pdf-filename-function key)))
    (if (file-exists-p pdf-file)
        (call-process "zathura" nil 0 nil pdf-file)
      (message "no pdf found for %s" key))))
Org Noter (link)
(use-package! org-noter
  :defer t
  :after (:any org pdf-view)
  :config
  (setq org-noter-always-create-frame nil)
  (setq org-noter-kill-frame-at-session-end nil)
  ;; Fraction of the frame that the document window will occupy when split
  (setq org-noter-doc-split-fraction '(0.6 . 0.6))
  ;; Save the last visited location automatically; when starting a new session, go to that location
  (setq org-noter-auto-save-last-location nil)
  ;; Add an empty line between each note's heading and content
  (setq org-noter-separate-notes-from-heading t)
  ;; List of paths to check (non recursively) when searching for a notes file
  (setq org-noter-notes-search-path "~/Cloud/brain")
  (defun org-noter-init-pdf-view ()
    (pdf-view-fit-page-to-window)
    (pdf-view-auto-slice-minor-mode)
    (run-at-time "0.5 sec" nil #'org-noter))
  (add-hook 'pdf-view-mode-hook 'org-noter-init-pdf-view)
  (map!
   :map pdf-view-mode-map
   (:desc "Insert Note"
     :n "i" #'org-noter-insert-note))
  )
Org Roam (link)
(use-package! org-roam
  :custom-face
  (org-roam-link ((t (:inherit org-link :foreground "#cc241d"))))
  :config
  (setq org-roam-directory "~/Cloud/brain/")
  (setq org-roam-completion-system 'helm)
  (setq org-roam-capture-templates
        `(("d" "default" plain (function org-roam--capture-get-point)
           "%?"
           :file-name "${slug}"
           :head ,(concat "#+TITLE: ${title}\n"
                          "#+SETUPFILE: ./setup/org-setup-file.org\n"
                          "#+HUGO_SECTION: zettels\n"
                          "\n"
                          "- Tags ::\n"
                          "\n"
                          "* Bibliography                                                        :ignore:\n"
                          "bibliography:./biblio/references.bib"
                          )
           :unnarrowed t)))
  (setq org-roam-capture-ref-templates
        `(("r" "ref" plain (function org-roam--capture-get-point)
           "%?"
           :file-name "${slug}"
           :head ,(concat "#+TITLE: ${title}\n"
                          "#+SETUPFILE: ./setup/org-setup-file.org\n"
                          "#+HUGO_SECTION: websites\n"
                          "#+ROAM_KEY: ${ref}\n"
                          "\n"
                          "- Tags ::\n"
                          )
           :unnarrowed t)))
  )
(defun tdh-org-roam--backlinks-list (file)
  (if (org-roam--org-roam-file-p file)
      (--reduce-from
       (concat acc (format "- [[file:%s][%s]]\n"
                           (file-relative-name (car it) org-roam-directory)
                           (org-roam--get-title-or-slug (car it))))
       "" (org-roam-db-query [:select [from] :from links :where (= to $s1)] file))
    ""))
(defun tdh-org-export-preprocessor (backend)
  (let ((links (tdh-org-roam--backlinks-list (buffer-file-name))))
    (unless (string= links "")
      (save-excursion
        (goto-char (point-max))
        (insert (concat "\n* Backlinks\n") links)))))
(add-hook 'org-export-before-processing-hook 'tdh-org-export-preprocessor)
Helm-Bibtex (link)
(use-package! helm-bibtex
  :after-call helm-bibtex
  :init
  :config
  ;; Bibliography file
  (setq bibtex-completion-bibliography "~/Cloud/brain/biblio/references.bib")
  ;; Directory with all the pdfs
  (setq bibtex-completion-library-path "~/Cloud/pdfs")
  ;; Directory with notes files
  (setq bibtex-completion-notes-path "~/Cloud/brain/")
  (setq bibtex-completion-notes-extension ".org")
  (setq bibtex-completion-pdf-extension '(".pdf" ".djvu"))
  ;; Use "tags" field when looking for bib entries
  (setq helm-bibtex-additional-search-fields '(tags))
  (setq helm-bibtex-full-frame nil)
  ;; Display of bibtex entries with helm
  (setq bibtex-completion-display-formats
        '((t . "${author:36} ${title:*} ${year:4} ${=type=:7} ${=has-note=:1}")))
  ;; Special symbols for notes and pdf
  (setq bibtex-completion-pdf-symbol "⌘")
  (setq bibtex-completion-notes-symbol "✎")
  ;; Template used when creating new Note file
  (setq bibtex-completion-notes-template-multiple-files (concat "#+TITLE: ${title}\n"
                                                                "#+SETUPFILE: ./setup/org-setup-file.org\n"
                                                                "#+HUGO_SECTION: ${=type=}\n"
                                                                "#+ROAM_KEY: ${=key=}\n"
                                                                "\n"
                                                                "- Tags ::\n"
                                                                "- Reference :: cite:${=key=}\n"
                                                                "- Author(s) :: ${author}\n"
                                                                "- Year :: ${year}\n"
                                                                "\n"
                                                                "* ${author-abbrev} (${year}): ${title} :${=type=}:ignore:\n"
                                                                ":PROPERTIES:\n"
                                                                ":NOTER_DOCUMENT: ../pdfs/${=key=}.pdf\n"
                                                                ":END:\n"
                                                                "\n"
                                                                "* Bibliography                                                        :ignore:\n"
                                                                "bibliography:./biblio/references.bib"
                                                                ))
  ;; Make "Edit notes" the default action
  (helm-delete-action-from-source "Edit notes" helm-source-bibtex)
  (helm-add-action-to-source "Edit notes" 'helm-bibtex-edit-notes helm-source-bibtex 0)
  (helm-delete-action-from-source "Open PDF Externally" helm-source-bibtex)
  (helm-add-action-to-source "Open PDF Externally" 'tdh-open-pdf-externally helm-source-bibtex 1)
  (helm-add-action-to-source "Insert Link to Note" 'tdh-insert-link-to-note helm-source-bibtex 2)
  )
(defun tdh-insert-link-to-note (key)
  "Insert a link to a note associated with the bibtex entry."
  (if (and bibtex-completion-notes-path
           (f-directory? bibtex-completion-notes-path))
      (let* ((path (f-join bibtex-completion-notes-path
                           (s-concat key bibtex-completion-notes-extension))))
        (if (file-exists-p path)
            (insert (concat "[[" (file-relative-name path) "][Notes]]"))
          (message "No note file associated"))
        )))
Open pdf externally
(defun tdh-open-pdf-externally (key) (call-process "zathura" nil 0 nil (nth 0 (-cons-to-list (bibtex-completion-find-pdf key)))))
Special Commands
(defun tdh-helm-bibtex-favorites (&optional arg) "Search Favorite BibTeX entries" (interactive "P") (helm-bibtex arg nil "favorite "))
List all element of the bibliography without pdf associated
(defun tdh-list-bib-without-pdf-associated ()
  (interactive)
  (bibtex-completion-init)
  (setq candidates (bibtex-completion-candidates))
  (defun canditate-is-pdf-present (candidate)
    (bibtex-completion-find-pdf-in-library (cdr (assoc "=key=" candidate)))
    )
  (setq candidates-without-pdf (remove-if #'canditate-is-pdf-present candidates))
  (setq candidate-without-pdf-names (mapcar
                                     (lambda (x) (cdr (assoc "title" x)))
                                     candidates-without-pdf))
  (with-output-to-temp-buffer "*bib-without-pdf*" (princ (string-join candidate-without-pdf-names "\n")))
  (switch-to-buffer-other-window "*bib-without-pdf*")
  )
Deft
(use-package! deft :custom (deft-directory "~/Cloud/brain/"))
Org-Roam-Bibtex (link)
Provides nice functions such as:
orb-find-non-ref-fileorb-insert-non-reforb-note-action
(use-package! org-roam-bibtex
  :hook (org-roam-mode . org-roam-bibtex-mode)
  :config
  (setq org-roam-bibtex-preformat-keywords `("=key=" "title" "author" "year" "author-abbrev" "=type="))
  (setq org-roam-bibtex-templates
        `(("r" "ref" plain (function org-roam-capture--get-point) ""
           :file-name "${=key=}"
           :head ,(concat "#+TITLE: ${title}\n"
                          "#+SETUPFILE: ./setup/org-setup-file.org\n"
                          "#+HUGO_SECTION: ${=type=}\n"
                          "#+ROAM_KEY: ${ref}\n"
                          "\n"
                          "- Tags ::\n"
                          "- Reference :: ${ref}\n"
                          "- Author(s) :: ${author}\n"
                          "- Year :: ${year}\n"
                          "\n"
                          "* ${author-abbrev} (${year}): ${title} :${=type=}:ignore:\n"
                          ":PROPERTIES:\n"
                          ":NOTER_DOCUMENT: ../pdfs/${=key=}.pdf\n"
                          ":END:\n"
                          "\n"
                          "* Bibliography                                                        :ignore:\n"
                          "bibliography:./biblio/references.bib"
                          )
           :unnarrowed t)))
  (setq orb-note-actions-user '(("Open with Zathura" . tdh-open-bib-with-zathura)))
  )
(defun tdh-open-bib-with-zathura (key)
  "Open the pdf corresponding to the reference KEY with Zathura"
  (if (listp key)
      (setq key (car key)))
  (call-process "zathura" nil 0 nil (org-ref-get-pdf-filename key)))
Org-Ref-Ox-Hugo (link)
This package is used to correctly format the bibliography and links when exporting to hugo.
(use-package! org-ref-ox-hugo
  :load-path "~/.config/doom/packages/org-ref-ox-hugo/"
  :config
  (add-to-list 'org-ref-formatted-citation-formats
               '("md"
                 ("article" . "${author}, *${title}*, ${journal}, *${volume}(${number})*, ${pages} (${year}). ${doi}")
                 ("inproceedings" . "${author}, *${title}*, In ${editor}, ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
                 ("book" . "${author}, *${title}* (${year}), ${address}: ${publisher}.")
                 ("phdthesis" . "${author}, *${title}* (${year}). ${school}.")
                 ("inbook" . "${author}, *${title}*, In ${editor} (Eds.), ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
                 ("incollection" . "${author}, *${title}*, In ${editor} (Eds.), ${booktitle} (pp. ${pages}) (${year}). ${address}: ${publisher}.")
                 ("proceedings" . "${editor} (Eds.), _${booktitle}_ (${year}). ${address}: ${publisher}.")
                 ("unpublished" . "${author}, *${title}* (${year}). Unpublished manuscript.")
                 ("misc" . "${author} (${year}). *${title}*. Retrieved from [${howpublished}](${howpublished}). ${note}.")
                 (nil . "${author}, *${title}* (${year}).")))
  (setq reference-link-class "reference-link")
  (setq bibtex-entry-class "bibtex-entry")
  )
LaTeX
Master file
(setq-default TeX-master nil)
Clean Output Files
(defun tdh-latex-clean ()
  "Clean LaTeX output using latexmk"
  (interactive)
  (async-shell-command
   ;; command and parameters
   "latexmk -c "
   (shell-quote-argument buffer-file-name)
   " &"
   ))
(map! :map LaTeX-mode-map
      :n ",C" 'tdh-latex-clean)
(add-hook 'TeX-mode-hook #'TeX-fold-mode)
PDF Viewer
(setq TeX-view-program-selection '((output-pdf "Zathura")))
(setq TeX-source-correlate-mode t)
(setq TeX-source-correlate-start-server t)
(setq TeX-source-correlate-method 'synctex)
(setq TeX-view-program-list
      '(("PDF Tools" TeX-pdf-tools-sync-view)))
Bibtex
(use-package! bibtex :config (bibtex-set-dialect 'BibTeX))
Matlab
Setup Matlab Mode
(setq matlab-shell-command "/home/thomas/.local/bin/matlab")
(setq matlab-shell-command-switches (list "-nodesktop -nosplash"))
(setq mlint-programs '("mlint" "/home/thomas/.local/bin/mlint"))
Setup Flycheck to work with mlint
(defvar mlint-executable "/home/thomas/.local/bin/mlint") (flycheck-define-command-checker 'matlab-mlint "A Matlab checker based on mlint." :command `(,mlint-executable source) :error-patterns '((warning line-start "L " line " (C " (1+ digit) "): " (message) line-end)) :modes '(matlab-mode)) (add-to-list 'flycheck-checkers 'matlab-mlint) ;; Automatic startup of flycheck for matlab (add-hook 'matlab-mode-hook 'flycheck-mode)
Completion in the Matlab Shell
(map! :map matlab-shell-mode-map
      :i "<tab>" 'matlab-shell-tab)
Beautify code
(defun tdh-matlab-beautify-buffer ()
  "Beautify Current Matlab Buffer"
  (interactive)
  ;; First verifies is the current file is a Matlab file
  (if (string= (file-name-extension (buffer-file-name)) "m")
      (progn
        (save-buffer)
        (matlab-shell-run-command (concat "MBeautify.formatFileNoEditor(\"" (buffer-file-name) "\", \"" (buffer-file-name) "\")"))
        (revert-buffer :ignore-auto :noconfirm))
    (message "Current buffer is not a matlab file")
    )
  )
Key Bindings
(defun tdh-matlab-add-breakpoint () (interactive) (matlab-shell-run-command (concat "dbstop in " (buffer-name) " at " (number-to-string (line-number-at-pos nil))))) (defun tdh-matlab-remove-breakpoint () (interactive) (matlab-shell-run-command (concat "dbclear in " (buffer-name) " at " (number-to-string (line-number-at-pos nil))))) (defun tdh-matlab-list-breakpoints () (interactive) (matlab-shell-run-command (concat "dbstatus " (buffer-name)))) (defun tdh-matlab-clear-breakpoints () (interactive) (matlab-shell-run-command (concat "dbclear in " (buffer-name)))) (defun tdh-matlab-go-to-file-directory () (interactive) (matlab-shell-run-command (concat "cd " (file-name-directory buffer-file-name))))
(map! :map matlab-mode-map
      :n ",g" 'tdh-matlab-go-to-file-directory
      :n ",da" 'tdh-matlab-add-breakpoint
      :n ",dr" 'tdh-matlab-remove-breakpoint
      :n ",dL" 'tdh-matlab-list-breakpoints
      :n ",dc" 'tdh-matlab-clear-breakpoints
      :n ",dl" 'gud-cont
      :n ",ds" 'gud-step
      :n ",dn" 'gud-next
      :n ",dq" 'gud-finish)
Mu4e
Resources
Documentation:
[ ]Mu4e documentation: http://www.djcbsoftware.nl/code/mu/mu4e/index.html#Top[ ]https://github.com/djcb/mu
Use contexts for multiple accounts:
[ ]https://vxlabs.com/2017/02/07/mu4e-0-9-18-e-mailing-with-emacs-now-even-better/[ ]http://cachestocaches.com/2017/3/complete-guide-email-emacs-using-mu-and-/[ ]https://notanumber.io/2016-10-03/better-email-with-mu4e/
Send math and source code:
Cheatsheet
| Command | Usage | 
|---|---|
C-j | 
Next mail | 
C-k | 
Previous mail | 
R/C/F | 
Reply/Compose/Forward | 
t | 
Move to Archive | 
d | 
Move to Trash | 
Helping function
This is a helper to help determine which account context I am in based on the folder in my maildir the email (eg. ~/.mail/nine27) is located in.
(defun mu4e-message-maildir-matches (msg rx)
  (when rx
    (if (listp rx)
        ;; If rx is a list, try each one for a match
        (or (mu4e-message-maildir-matches msg (car rx))
            (mu4e-message-maildir-matches msg (cdr rx)))
      ;; Not a list, check rx
      (string-match rx (mu4e-message-field msg :maildir)))))
Choose account label to feed msmtp -a option based on From header in Message buffer; This function must be added to message-send-mail-hook for on-the-fly change of From address before sending message since message-send-mail-hook is processed right before sending message.
(defun choose-msmtp-account ()
  (if (message-mail-p)
      (save-excursion
        (let*
            ((from (save-restriction
                     (message-narrow-to-headers)
                     (message-fetch-field "from")))
             (account
              (cond
               ((string-match "dehaeze.thomas@gmail.com" from) "gmail")
               ((string-match "thomas.dehaeze@esrf.fr" from) "esrf"))))
          (setq message-sendmail-extra-arguments (list '"-a" account))))))
Basic Config
(use-package! mu4e
  :config
  (setq mail-user-agent 'mu4e-user-agent
        mu4e-mu-binary "/usr/bin/mu"
        mu4e-maildir "~/.mail"
        mu4e-compose-format-flowed t
        mu4e-compose-in-new-frame nil
        mu4e-view-show-images t
        mu4e-html2text-command "w3m -dump -T text/html"
        mu4e-use-fancy-chars t
        mu4e-headers-include-related t
        mu4e-attachment-dir  "~/Downloads"
        message-kill-buffer-on-exit t
        mu4e-compose-signature-auto-include t
        mu4e-view-show-images t
        mu4e-view-show-addresses t)
  )
Additional config
(use-package! mu4e
  :config
  ;; Use imagemagick, if available.
  (when (fboundp 'imagemagick-register-types)
    (imagemagick-register-types))
  ;; Sometimes html email is just not readable in a text based client, this lets me open the
  ;; email in my browser.
  (add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser) t)
  ;; Spell checking ftw.
  (add-hook 'mu4e-compose-mode-hook 'flyspell-mode)
  ;; Use Helm to select mailboxes
  (setq mu4e-completing-read-function 'completing-read)
  ;; Don't ask for a 'context' upon opening mu4e
  (setq mu4e-context-policy 'pick-first)
  ;; Don't ask to quit... why is this the default?
  (setq mu4e-confirm-quit nil)
  )
Provide Information
(use-package! mu4e
  :config
  (setq mu4e-user-mail-address-list '("dehaeze.thomas@gmail.com" "thomas.dehaeze@esrf.fr")
        mu4e-compose-signature "Thomas Dehaeze\n"
        user-mail-address "dehaeze.thomas@gmail.com")
  ;; Default Folders
  (setq mu4e-sent-folder "/gmail/Sent"
        mu4e-drafts-folder "/gmail/Drafts"
        mu4e-trash-folder "/gmail/Trash"
        mu4e-refile-folder "/gmail/Archive")
  )
Receiving emails using mbsync
(use-package! mu4e
  :config
  (setq mu4e-get-mail-command "checkmail"
        mu4e-update-interval nil
        mu4e-change-filenames-when-moving t) ;; Fix for mbsync
  )
Contexts
(use-package! mu4e
  :config
  (setq mu4e-contexts
        `( ,(make-mu4e-context
             :name "gmail"
             :enter-func (lambda () (mu4e-message "Switch to the gmail context"))
             :match-func (lambda (msg) (when msg
                                         (string-prefix-p "/gmail" (mu4e-message-field msg :maildir))))
             :leave-func (lambda () (mu4e-clear-caches))
             :vars '(
                     (user-mail-address . "dehaeze.thomas@gmail.com")
                     (user-full-name        . "Thomas Dehaeze")
                     (mu4e-sent-folder . "/gmail/Sent")
                     (mu4e-trash-folder . "/gmail/Trash")
                     (mu4e-drafts-folder . "/gmail/Drafts")
                     (mu4e-refile-folder . "/gmail/Archive")
                     (mu4e-compose-signature  . "Thomas Dehaeze\n")
                     ))
           ,(make-mu4e-context
             :name "esrf"
             :enter-func (lambda () (mu4e-message "Switch to the esrf context"))
             :match-func (lambda (msg) (when msg
                                         (string-prefix-p "/esrf" (mu4e-message-field msg :maildir))))
             :leave-func (lambda () (mu4e-clear-caches))
             :vars '(
                     (user-mail-address . "thomas.dehaeze@esrf.fr")
                     (user-full-name        . "Thomas Dehaeze")
                     (mu4e-sent-folder . "/esrf/Sent")
                     (mu4e-trash-folder . "/esrf/Trash")
                     (mu4e-drafts-folder . "/esrf/Drafts")
                     (mu4e-refile-folder . "/esrf/Archive")
                     (mu4e-compose-signature  . "Thomas Dehaeze\n")
                     ))
           ))
  )
Sending mails
(use-package! mu4e
  :config
  (setq message-send-mail-function 'message-send-mail-with-sendmail
        sendmail-program "/usr/bin/msmtp"
        user-full-name "Thomas Dehaeze")
  ;; This prevents saving the email to the Sent folder since gmail will do this for us on their end.
  (setq mu4e-sent-messages-behavior 'delete)
  ;; Use the correct account context when sending mail based on the from header.
  (setq message-sendmail-envelope-from 'header)
  (add-hook 'message-send-mail-hook 'choose-msmtp-account)
  )
Bookmarks
(use-package! mu4e
  :config
  (setq mu4e-bookmarks `(,(make-mu4e-bookmark
                          :name "All Inboxes"
                          :query "maildir:/gmail/Inbox OR maildir:/esrf/Inbox"
                          :key ?i)
                         ("flag:unread" "Unread messages" ?u)
                         ("date:today..now" "Today's messages" ?t)
                         ("date:7d..now" "Last 7 days" ?w)))
  )
Doom init.el
(when noninteractive
  (after! undo-tree
    (global-undo-tree-mode -1)))
(doom! :completion
       company           ; the ultimate code completion backend
       helm              ; the *other* search engine for love and life
       ivy               ; a search engine for love and life
       :ui
       doom              ; what makes DOOM look the way it does
       deft
       hl-todo           ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
       hydra
       (modeline
        +light)          ; snazzy, Atom-inspired modeline, plus API
       ophints           ; highlight the region an operation acts on
       (popup            ; tame sudden yet inevitable temporary windows
        +all             ; catch all popups that start with an asterix
        +defaults)       ; default popup rules
       unicode           ; extended unicode support for various languages
       vc-gutter         ; vcs diff in the fringe
       vi-tilde-fringe   ; fringe tildes to mark beyond EOB
       workspaces        ; tab emulation, persistence & separate workspaces
       :editor
       (evil +everywhere); come to the dark side, we have cookies
       fold              ; (nigh) universal code folding
       rotate-text       ; cycle region at point between text candidates
       snippets          ; my elves. They type so I don't have to
       word-wrap         ; soft wrapping with language-aware indent
       :emacs
       (dired +icons)    ; making dired pretty [functional]
       electric          ; smarter, keyword-based electric-indent
       (ibuffer +icons)  ; interactive buffer management
       vc                ; version-control and Emacs, sitting in a tree
       :term
       eshell            ; a consistent, cross-platform shell (WIP)
       vterm
       :tools
       debugger          ; Stepping through code, to help you add bugs
       (eval +overlay)     ; run code, run (also, repls)
       (lookup           ; helps you navigate your code and documentation
        +docsets)        ; ...or in Dash docsets locally
       lsp
       magit             ; a git porcelain for Emacs
       ;;pass              ; password manager for nerds
       pdf               ; pdf enhancements
       eval
       biblio
       :checkers
       syntax          ; tasing you for every semicolon you forget
       spell          ; tasing you for misspelling mispelling
       :lang
       data              ; config/data formats
       emacs-lisp        ; drown in parentheses
       go
       (javascript
        +lsp)
       latex            ; writing papers in Emacs has never been so fun
       ;; markdown          ; writing docs for people to ignore
       (org              ; organize your plain life in plain text
        +dragndrop       ; drag & drop files/images into org buffers
        +hugo            ; use Emacs for hugo blogging
        +roam         ;
        +present)        ; using org-mode for presentations
       python            ; beautiful is better than ugly
       (sh                ; she sells {ba,z,fi}sh shells on the C xor
        +lsp)
       (web
        +lsp)
       :email
       (mu4e +gmail)
       :app
       calendar
       ;;(rss +org)        ; emacs as an RSS reader
       ;;write             ; emacs for writers (fiction, notes, papers, etc.)
       :config
       literate
       (default +bindings)
       )
Doom packages.el
(package! poet-theme) (package! org-alert) (package! org-gcal) (package! ox-latex-subfigure :recipe (:host github :repo "linktohack/ox-latex-subfigure")) (package! matlab-mode :recipe (:host github :repo "matlab-mode/mirror")) (package! org-ref) (package! org-roam-bibtex) (package! org-ql) (package! org-fancy-priorities) (package! evil-escape :disable t) (package! dired-narrow)