;;; org-settings.el --- Org settings  -*- lexical-binding: t -*-

;; Package-Requires: ((emacs) (org-mode) (org-bullets) (org-cliplink))

;; This file is not part of GNU Emacs.

;; direct LaTeX (not org)
;; hyphen via AUCTeX (not installed)
;; https://tex.stackexchange.com/questions/282448/why-does-emacs-or-auctex-turns-into

;;; Commentary:
;; `org-export-default-language'
;; `org-options-keywords'

;; * Overview of modes and commands
;; --------------------------------
;;
;; ** `org-appear'
;; ---------------
;; auto toogle entities, emphasis markers, links, subscripts and superscripts,
;; keywords
;; `org-appear-autoentities', `org-appear-autoemphasis', `org-appear-autolinks'
;; `org-appear-autosubmarkers', `org-appear-autokeywords'
;; and from `org': `org-pretty-entries', `org-hide-emphasis-markers',
;; `org-link-descriptive', `org-hidden-keywords'
;;
;; ** Export `ox-reveal'
;; ---------------------
;; (org-export-get-all-options 'reveal)
;;
;; *** KEYWORDs
;; ------------
;; *Note*: Using an option which is also set in the configuration will
;; overwrite it.
;;
;; #+REVEAL_ROOT:
;; - path to reveal.js root directory, can be used once
;; - is defined in the configuration, see `org-reveal-root'
;; 
;; #+REVEAL_EXTRA_CSS:
;; - path to css file, can be used multiple times
;; - is defined in the configuration, see `org-reveal-extra-css'
;;
;; #+REVEAL_POSTAMBLE:
;; - postamble content, can be used once
;; - is defined in the configuration, see `org-reveal-postamble'
;;
;; #+REVEAL_HLEVEL:
;; - can be configured, see `org-reveal-hlevel'
;;
;; #+REVEAL: split
;; #+REVEAL: split:t
;;
;; #+REVEAL_THEME:
;;
;; #+OPTIONS: reveal_title_slide:auto|"string"|nil
;; #+REVEAL_TITLE_SLIDE:
;; - path to css file, can be used multiple times
;; - can be configured, see `org-reveal-title-slide'
;;
;; #+REVEAL_TITLE_SLIDE_BACKGROUND: #123456|rgb(0,0,0)|./image/path.jpg
;; #+REVEAL_TITLE_SLIDE_BACKGROUND_SIZE: 200px
;; #+REVEAL_TITLE_SLIDE_BACKGROUND_REPEAT: repeat
;; #+REVEAL_TITLE_SLIDE_BACKGROUND_OPACITY: 0.2
;;
;; #+REVEAL_TOC_SLIDE_BACKGROUND: #123456|rgb(0,0,0)|./image/path.jpg
;; #+REVEAL_TOC_SLIDE_BACKGROUND_SIZE: 200px
;; #+REVEAL_TOC_SLIDE_BACKGROUND_REPEAT: repeat
;; #+REVEAL_TOC_SLIDE_BACKGROUND_OPACITY: 0.2
;;
;; #+REVEAL_DEFAULT_SLIDE_BACKGROUND: #123456|rgb(0,0,0)|./image/path.jpg
;; #+REVEAL_DEFAULT_SLIDE_BACKGROUND_SIZE: 200px
;; #+REVEAL_DEFAULT_SLIDE_BACKGROUND_POSITION:
;; #+REVEAL_DEFAULT_SLIDE_BACKGROUND_REPEAT: repeat
;; #+REVEAL_DEFAULT_SLIDE_BACKGROUND_TRANSITION:
;;
;; #+OPTIONS: reveal_width: org-reveal-width
;; #+OPTIONS: reveal_height: org-reveal-height
;; #+REVEAL_MARGIN: org-reveal-margin
;; #+REVEAL_MIN_SCALE: org-reveal-min-scale
;; #+REVEAL_MAX_SCALE: org-reveal-max-scale
;;
;; #+REVEAL_INIT_OPTIONS: slideNumber:true|“h.v”|“h/v”|“c”|“c/t”
;;
;; #+REVEAL_SLIDE_HEADER: css class slide-header
;; #+REVEAL_SLIDE_FOOTER: css class slide-footer
;; #+OPTIONS: reveal_global_header:t reveal_global_footer:t
;;
;; *** Properties
;; --------------
;; see `org-reveal-slide-section-tag' (org-element-property :xxx headline)
;; :PROPERTIES:
;; :reveal_background: #123456|rgb(0,0,0)|./image/path.jpg
;; :reveal_background_trans: slide
;; :reveal_background_size: 200px
;; :reveal_background_repeat: repeat
;; :reveal_background_opacity: 0.2
;; :reveal_background_iframe: https://domain.tld
;; :END:
;;
;; *** Variables
;; -------------
;; - `org-reveal-root' - string
;; - `org-reveal-extra-css' - string - multiple values separated by \n
;; - `org-reveal-postamble' - string - only one line
;; - `org-reveal-single-file' - t|nil
;; - `org-reveal-hlevel'
;;
;; {{(my-list-to-org-table (org-export-get-all-options 'reveal))}}
;; 

;;; Code:
(defgroup my-org nil
  "My org-mode concept mapping"
  :prefix "my-org-"
  :group 'my)

(defcustom my-org-default-notes-file (convert-standard-filename "~/.notes")
  "Documention see `org-default-notes-file' in `org.el'."
  :group 'my-org
  :type '(choice file (const "~/.notes") (const "~/Sync/notes.org")))

(defcustom my-org-agenda-files nil
  "Documention see `org-agenda-files' in `org.el'."
  :group 'my-org
  :type '(choice
	  (repeat :tag "List of files and directories" file)
	  (file :tag "Store list in a file\n" :value "~/.agenda_files")
    (const "~/Sync/tasks.org")))

(defcustom my-org-refile-targets nil
  "Documention see `org-refile-targets' in `org.el'.

Example:
  Current buffer (nil) :maxlevel 3
  All agenda files (variable org-agenda-files) Max Level number 3
  Variable org-default-notes-file Max Level number 3"
  :group 'my-org
  :type '(repeat
	  (cons
	   (choice :value org-agenda-files
		   (const :tag "All agenda files" org-agenda-files)
		   (const :tag "Current buffer" nil)
		   (function) (variable) (file))
	   (choice :tag "Identify target headline by"
		   (cons :tag "Specific tag" (const :value :tag) (string))
		   (cons :tag "TODO keyword" (const :value :todo) (string))
		   (cons :tag "Regular expression" (const :value :regexp) (regexp))
		   (cons :tag "Level number" (const :value :level) (integer))
		   (cons :tag "Max Level number" (const :value :maxlevel) (integer))))))

(defcustom my-org-publish-project-base-directory "~/org/project/"
  "Documention see :base-directory of `org-publish-project-alist'.

Used for the example in `my-org-publish-project-alist'."
  :group 'my-org
  :type '(choice directory (const "~/org/project/") (const "~/Sync/workspace/emacs/org/")))

(defcustom my-org-publish-project-publish-directory "~/public_html/"
  "Documention see :publish-directory of `org-publish-project-alist'.

Used for the example in `my-org-publish-project-alist'."
  :group 'my-org
  :type '(choice directory (const "~/public_html/")))

(defcustom my-org-publish-project-alist nil
  "Documention see `org-publish-project-alist' in `ox-publish.el'.

Example defines
  org-notes and org-static with
    base-directory to `my-org-publish-project-base-directory'
    publishing-directory `my-org-publish-project-publish-directory'."
  :group 'my-org
  :type '(choice alist
           (const :tag "Example" :value (list
            ;; The notes component
            (list "org-notes"
             :base-directory my-org-publish-project-base-directory
             :base-extension "org"
             :publishing-directory my-org-publish-project-publish-directory
             :recursive t
             :publishing-function org-html-publish-to-html
             ;;:publishing-function org-html-publish-to-tufte-html
             :headline-levels 4               ; Just the default for this project.
             :auto-preamble t
             :auto-sitemap t                  ; Generate sitemap.org automatically...
             :sitemap-filename "sitemap.org"  ; ... call it sitemap.org (it's the default)...
             :sitemap-title "Sitemap"         ; ... with title 'Sitemap'.
             )
            ;; The static component
            (list "org-static"
             :base-directory my-org-publish-project-base-directory
             :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
             :publishing-directory my-org-publish-project-publish-directory
             :recursive t
             :publishing-function org-publish-attachment
             )
            ;; The publish component
            (list "org" :components (list "org-notes" "org-static"))))))

(defcustom my-org-brain-path (expand-file-name "brain" "~/org")
  "Documention see `org-brain-path' in `ox-brain.el'."
  :group 'my-org
  :type '(choice directory
                 (const (expand-file-name "brain" "~/org"))
                 (const "~/Sync/workspace/emacs/org-brain")))

(defun my-org-commentary ()
  "View org documentation in `outline-mode'."
  (interactive)
  (let ((buf "*Org: Commentary*"))
    ;; kill buffer if aleady open
    (when (buffer-live-p (get-buffer buf))
      (kill-buffer buf))
    ;; Use `finder-commentary' to generate the buffer.
    (require 'finder)
    (cl-letf (((symbol-function 'finder-summary) #'ignore))
      (finder-commentary "org-settings"))
    ;; change commentary text
    (let ((inhibit-read-only t))
      ;;(insert "org-settings.el\n\n")
      ;; point under headline
      (forward-line 1)
      (save-excursion
        ;; remove --- under headlines
        (while (re-search-forward "^-+$" nil :noerror)
          (replace-match ""))
        ;; replace `xxx' with =xxx=
        (goto-char (point-min))
        (while (re-search-forward (rx (and "`" (group (+? anything)) "'")) nil :noerror)
          (replace-match (concat "=" (match-string 1) "=")))
        ;; find {{xxx}} and eval xxx
        (goto-char (point-min))
        (while (re-search-forward (rx (and "{{" (group (+? anything)) "}}")) nil :noerror)
          (replace-match (eval (my-eval-string (match-string 1)))))
        ;; align all tables
        (org-table-map-tables 'org-table-align)
        ))
    (rename-buffer buf)
    ;; Enable `org-mode' and `view-mode' for user convenience.
    (org-mode)
    (view-mode 1)))

;; uses the org version from the org ELPA repository instead of the
;; one shipped with emacs. Therefore, any org related code should not
;; be loaded before, otherwise both versions will be loaded and will
;; conflict.
(use-package org
  :delight (org-mode "Org")  ;; "Org " "\u01F15E"
  :defer t
  :after (ob-csharp)
  ;;:bind (("C-c <del>" . org-mark-ring-goto))  ;; normally at C-c & but it is redefined by yasnippet
  :init
  (setq org-export-backends '(ascii html icalendar latex md odt reveal tufte))
  :config
  (setq org-hidden-keywords '(author date title email subtitle))  ;; see also `org-appear'
  (setq org-hide-emphasis-markers t)               ;; see also `org-appear'
  (setq org-startup-folded nil)                    ;; nil = showall = #+STARTUP: showall
  (setq org-startup-with-inline-images t)          ;; #+STARTUP: inlineimages|noinlineimages, show inline images when loading a new Org file
  (setq org-use-sub-superscripts '{})              ;; braces are *required* in order to trigger interpretations as sub/superscript, see also `org-export-with-sub-superscripts'. C-c C-x \ (`org-toggle-pretty-entities')
  (setq org-pretty-entities nil)                   ;; so much trouble in an article, see also `org-appear' and [C-c C-x \] (`org-toggle-pretty-entities')
  (setq org-pretty-entities-include-sub-superscripts t)  ;; if `org-pretty-entities' is active include also sub-superscripts.
  (setq org-image-actual-width '(600))             ;; image width displayed in org
  (setq org-startup-with-latex-preview t)          ;; #+STARTUP: latexpreview|nolatexpreview
  ;; scale of latex image preview via `org-format-latex-options'. setting this here will overwrite settings in custom.el.
  ;; see also `org-preview-latex-process-alist', `org-preview-latex-default-process' and `org-format-latex-header' using `org-latex-default-packages-alist' and `org-latex-packages-alist'
  (add-to-list 'org-latex-default-packages-alist '("" "eurosym" t) t) ;; add \euro{} (also to latex snippets)
  (setq org-tag-persistent-alist '(("ignore" . ?i) ("noexport" . ?n)))
  ;; todo see also org-todo-keyword-faces and org-superstar-todo-bullet-alist
  (setq org-todo-keywords                          ;; (x!) record a time stamp, (x@) add a note (with time), (y/z) entering the state / leaving the state
        '((sequence "TODO(t)" "WAIT(w)" "|" "DONE(d)" "CANC(c)")))
  (setq org-hierarchical-todo-statistics nil)      ;; TODO statistics covers all entries in the subtree.
  (setq org-refile-use-outline-path t)             ;; show levels
  (setq org-outline-path-complete-in-steps nil)    ;; not in steps bc of using ivy completion
  (setq org-default-notes-file my-org-default-notes-file)
  (setq org-agenda-files my-org-agenda-files)
  (setq org-refile-targets my-org-refile-targets)
  (defun my-org-refile-target-verify-function ()
    "exclude done keywords of todos."
    (not
     (member
      (nth 2 (org-heading-components))  ;; get todo keyword from current heading
      org-done-keywords)))              ;; is filled buffer-wise
  (setq org-refile-target-verify-function 'my-org-refile-target-verify-function)

  ;; C-c C-c for code blocks (otherwise e.g.: No org-babel-execute function for shell)
  (org-babel-do-load-languages
   'org-babel-load-languages
   '(;; t enabled, nil disabled
     (awk . t)
     (C . t)
     (calc . t)
     (csharp . t)
     (ditaa . t)
     (dot . t)
     (emacs-lisp . t)
     (gnuplot . t)
     (haskell . t)
     (js . t)
     (latex . t)
     (octave . t)
     (plantuml . t)
     (python . t)
     (R . t)
     ;; Error message regarding R:
     ;; (invalid-function org-babel-header-args-safe-fn)
     ;; Invalid function: org-babel-header-args-safe-fn
     ;; M-x byte-compile-file <path to org>/ob-R.el
     ;; restart emacs. The compilation of ob-R.el must be done twice if necessary
     (shell . t)
     (sql . t)))

  (add-to-list 'image-file-name-extensions "eps" t))  ;; TODO: eps not needed?

;; org core libs
(use-package org-src
  :defer t
  :config
  (setq org-edit-src-content-indentation 0)
  (setq org-src-preserve-indentation t))

(use-package org-contrib
  :after (org))

;;; org-contrib libs

;; Make invisible parts of Org elements appear visible.
(use-package org-appear
  :hook (org-mode . org-appear-mode)
  :config
  (setq org-appear-autoentities t)    ;; toogle entities: \alpha -> ɑ, needs `org-pretty-entities' active
  (setq org-appear-autoemphasis t)    ;; toggle emphasis markers, t by default, needs `org-hide-emphasis-markers' active
  (setq org-appear-autolinks t)       ;; toogle links, needs `org-link-descriptive' active
  (setq org-appear-autosubmarkers t)  ;; toogle subscripts and superscripts: ^3 -> ³, needs `org-pretty-entities' active
  (setq org-appear-autokeywords t))   ;; toogle keywords: #+TITLE: foo -> foo, needs `org-hidden-keywords' active

(use-package org-brain  ;; uses org-id If you find that org-brain is missing entries, or list entries which doesn’t exist, try using M-x org-brain-update-id-locations, which syncs the org-brain entries with the org-id caching system.
  :commands (org-brain-visualize)
  :init
  (setq org-brain-path my-org-brain-path)
  :config
  (require 'org-capture)
  ;; make org-brain commands more accessable if you edit entries from org-mode
  (bind-key "C-c B" 'org-brain-prefix-map org-mode-map)
  ;; org-brain use org-id in order to speed things up. Because of
  ;; this, the variable org-id-track-globally should be t (which it
  ;; already is by default). You may want to modify
  ;; org-id-locations-file too. If you add entries to org-brain
  ;; directly from org-mode you must assign headliens an ID. A
  ;; comfortable way to do this is with the command
  ;; org-brain-ensure-ids-in-buffer. Even more comfortable is to add
  ;; that to before-save-hook, so that it runs when saving.
  (add-hook 'before-save-hook #'org-brain-ensure-ids-in-buffer)
  ;; to add information at the end of an entry, without visiting the file.
  (push '("b" "Brain" plain (function org-brain-goto-end)
          "* %i%?" :empty-lines 1)
        org-capture-templates)
  ;; (setq org-brain-visualize-default-choices 'all)
  ;; (setq org-brain-show-resources t)
  ;; (setq org-brain-show-text t)
  ;; (setq org-brain-title-max-length 12)
  ;; Some users find it confusing having both headline entries and
  ;; file entries (see below). It may be preferable to only use
  ;; headline entries, by setting org-brain-include-file-entries to
  ;; nil. If doing this, you should probably also set
  ;; org-brain-file-entries-use-title to nil. Another possibility is
  ;; if you’re only using file entries, in which case you can set
  ;; org-brain-scan-for-header-entries to nil.
  ;; (setq org-brain-include-file-entries nil)
  ;; (setq org-brain-file-entries-use-title nil)

  (require 'all-the-icons)
  (defun org-brain-insert-resource-icon (link)
    "Insert an icon, based on content of org-mode LINK."
    (insert (format "%s "
                    (cond ((string-prefix-p "brain:" link)
                           (all-the-icons-fileicon "brain"))
                          ((string-prefix-p "info:" link)
                           (all-the-icons-octicon "info"))
                          ((string-prefix-p "help:" link)
                           (all-the-icons-material "help"))
                          ((string-prefix-p "http" link)
                           (all-the-icons-icon-for-url link))
                          (t
                           (all-the-icons-icon-for-file link))))))
  (add-hook 'org-brain-after-resource-button-functions #'org-brain-insert-resource-icon)
  
  (require 'deft)
  (defun org-brain-deft ()
    "Use `deft' for files in `org-brain-path'."
    (interactive)
    (let ((deft-directory org-brain-path)
          (deft-recursive t)
          (deft-extensions '("org")))
      (deft)))

  (require 'org-cliplink)
  (defun org-brain-cliplink-resource ()
    "Add a URL from the clipboard as an org-brain resource.
Suggest the URL title as a description for resource."
    (interactive)
    (let ((url (org-cliplink-clipboard-content)))
      (org-brain-add-resource
       url
       (org-cliplink-retrieve-title-synchronously url)
       t)))
  (define-key org-brain-visualize-mode-map (kbd "L") #'org-brain-cliplink-resource))

(use-package org-capture
  :defer t
  :config
  ;; https://www.gnu.org/software/emacs/manual/html_node/org/Capture-templates.html
  (add-to-list 'org-capture-templates
               '(;; put entries under the heading 'Tasks' in default notes file
                 ("t" "Todo" entry (file+headline "" "Tasks")  ;; empty string is the file, e.g. "~/org/gtd.org"
                  "* TODO %?\n  %i\n  %a")))
  (add-to-list 'org-capture-templates
               '(;; put entries under a date tree (year - month - day - entry) in the default file
                 ("j" "Journal" entry (file+olp+datetree "")   ;; empty string is the file, e.g. "~/org/journal.org"
                  "* %?\nEntered on %U\n  %i\n  %a"))))
  ;; see also org-cliplink K, org-brain b

(use-package org-cliplink
  :after (org)
  :config
  (defun my-org-link-description-update ()
    "."
    ;; content is the link description
    (interactive)
    (let ((elem (org-element-context)))
      (if (eq (car elem) 'link)
          (let* ((content-begin (org-element-property :contents-begin elem))
                 (content-end (org-element-property :contents-end elem))
                 (link-begin (org-element-property :begin elem))
                 (link-end (org-element-property :end elem))
                 (raw-link (org-element-property :raw-link elem)))
            (save-excursion
              ;; if content-begin (and content-end) is not nil (will be nil if there is no description)
              (if (and content-begin content-end)
                  (progn
                    (delete-region content-begin content-end)
                    (insert (org-cliplink-retrieve-title-synchronously raw-link)))
                (delete-region link-begin link-end)
                (insert (org-cliplink-org-mode-link-transformer
                         raw-link (org-cliplink-retrieve-title-synchronously raw-link)))))))))
  
  (with-eval-after-load 'org-capture
    (add-to-list 'org-capture-templates
                 '("K" "Cliplink capture task" entry (file "")
                   "* TODO %(org-cliplink-capture) \n  SCHEDULED: %t\n" :empty-lines 0))))

(use-package org-collector  ;; collect properties into tables, using #+BEGIN: propview
  :after (org))

(use-package org-drill  ;; requires persist https://elpa.gnu.org/packages/persist.html
  :commands org-drill)

(use-package org-faces
  :defer t
  :config
  (setq org-todo-keyword-faces                 ;; TODO keywords
        '(("TODO" . "LightSkyBlue4")           ;; org-warning (bold red), DeepSkyBlue3
          ("WAIT" . "LightSkyBlue4")           ;;
          ("DONE" . "#5e5079")                 ;; DarkSlateGray4 PaleTurquoise4, CadetBlue4, LightSkyBlue4
          ("CANC" . "#5e5079")                 ;; 
          ("STARTED" . "yellow")
          ("CANCELED" . (:foreground "blue" :weight bold)))))

(use-package org-fancy-priorities
  :after (org)
  :delight (org-fancy-priorities-mode "Fp")  ;; FancyPriorities  "\u24C5"
  :hook (org-mode . org-fancy-priorities-mode)
  :config
  ;; 🅐🅑🅒🅓 🅰🅱🅲🅳 ❗⬆⬇☕ ⚡⮬⮮☕
  ;; HIGH MID LOW OPTIONAL
  ;; ?x to get the interger of character
  ;; (setq org-fancy-priorities-list
  ;;       '((?A . "HIGH")
  ;;         (?B . "MID")
  ;;         (?C . "LOW")
  ;;         (?D . "OPTIONAL")
  ;;         (?1 . "⚡")
  ;;         (?2 . "⮬")
  ;;         (?3 . "⮮")
  ;;         (?4 . "☕")
  ;;         (?I . "Important")))
  (setq org-fancy-priorities-list
        '((?A . "🅰")
          (?B . "🅱")
          (?C . "🅲")
          (?D . "🅳")))
  ;; (setq org-priority-faces
  ;;       '((?A :foreground "#df5f5f" :weight bold)  ;; "IndianRed1"
  ;;         (?B :foreground "DarkOrange1")
  ;;         (?C :foreground "yellow1")
  ;;         (?D :foreground "green1")  ;; DeepSkyBlue1
  ;;         (?1 :foreground "#df5f5f" :weight bold)
  ;;         (?2 :foreground "DarkOrange1")
  ;;         (?3 :foreground "yellow1")
  ;;         (?4 :foreground "green1")
  ;;         (?I :foreground "#df5f5f" :weight bold)))
  (setq org-priority-faces
        (list (list ?A :foreground "#df5f5f" :height (- (face-attribute 'default :height) 20) :weight 'bold)
              (list ?B :foreground "DarkOrange1" :height (- (face-attribute 'default :height) 20) :weight 'bold)
              (list ?C :foreground "yellow1" :height (- (face-attribute 'default :height) 20) :weight 'bold)
              (list ?D :foreground "green1" :height (- (face-attribute 'default :height) 20) :weight 'bold)
              (list ?1 :foreground "#df5f5f" :weight 'bold)
              (list ?2 :foreground "DarkOrange1")
              (list ?3 :foreground "yellow1")
              (list ?4 :foreground "green1")
              (list ?I :foreground "#df5f5f" :weight 'bold))))

(use-package org-fragtog
  :hook (org-mode . org-fragtog-mode))

(use-package org-id  ;; used by org-brain
  :defer t
  :config
  ;; (setq org-id-track-globally t)  ;; default is t
  (setq org-id-locations-file (concat user-cache-directory ".org-id-locations")))

(use-package org-mouse  ;; to load mouse features, like clicking on the bullet of a heading
  :after (org))

(use-package org-num    ;; numbering of headings
  :after (org)
  :delight (org-num-mode "#")  ;; o# "\uFF03"
  :config
  (setq org-num-skip-tags '("ignore"))
  (setq org-num-skip-unnumbered t))

(use-package org-roam
  ;; builds SQLite db and requires gcc or clang, check `org-roam--sqlite-available-p'
  ;; create roam directory beforehand
  ;; do not sync the db file, only the org files.
  ;; to sync manually run `org-roam-db-sync' from a file within a roam directory
  ;; to greate a node inside an org file, on a header execute `org-id-get-create'
  :bind (("C-c r l" . org-roam-buffer-toggle)
         ("C-c r L" . org-roam-buffer-display-dedicated)
         ("C-c r f" . org-roam-node-find)
         ("C-c r n" . org-roam-node-random)
         ("C-c r c" . org-roam-capture)
         (:map org-mode-map
               (("C-c r i" . org-roam-node-insert)
                ("C-c r a" . org-roam-alias-add)
                ("C-c r A" . org-roam-alias-remove)
                ("C-c r d" . org-id-get-create)  ;; create id for file or header
                ("C-c r t" . org-roam-tag-add)
                ("C-c r T" . org-roam-tag-remove)
                ("C-c r r" . org-roam-ref-add)
                ("C-c r R" . org-roam-ref-remove)))
         ;; Dailies
         ("C-c r j" . org-roam-dailies-capture-today))
  :init
  (setq org-roam-v2-ack t)  ;; no migration warning
  (setq org-roam-directory (expand-file-name "~/Sync/workspace/emacs/org-roam"))  ;; check if folder exists
  (setq org-roam-db-location (concat user-cache-directory "org-roam.db"))
  ;; (setq org-roam-graph-viewer nil)  
  :config
  (org-roam-db-autosync-mode)  ;; sync on file change
  ;;(org-roam-setup)
  )

(use-package org-roam-graph
  :bind (("C-c r g" . org-roam-graph)))

(use-package org-roam-ui
  :after (org-roam)
  :commands (org-roam-ui-mode)
  :config
  (setq org-roam-ui-sync-theme t)
  (setq org-roam-ui-follow t)
  (setq org-roam-ui-update-on-save t)
  ;;(setq org-roam-ui-open-on-start t)
  )

(use-package org-sticky-header
  :after (org org-table-sticky-header)  ;; org-table-sticky-header-mode must be set before
  :hook (org-mode . org-sticky-header-mode)
  :config
  ;;(setq org-sticky-header-always-show-header nil)
  (setq org-sticky-header-full-path 'reversed))

(use-package org-superstar
  ;; formerly
  ;;(require 'org-bullets)
  ;;(add-hook 'org-mode-hook 'org-bullets-mode)
  :hook (org-mode . org-superstar-mode)  ;; defers the loading.
  :config
  (setq org-superstar-leading-bullet " ·")  ;; " ․" " ·" " ⚫" or to hide: ?\s
  (setq org-superstar-prettify-item-bullets t)  ;; can cause slowdown when using a lot of lists (thousands), run command org-superstar-toggle-lightweight-list or set this variable to nil or see hack on the source web page
  (setq org-superstar-remove-leading-stars nil)  ;; to remove the indentation
  (setq org-superstar-special-todo-items t)  ;; using symbols defined in org-superstar-todo-bullet-alist
  ;; (setq org-superstar-todo-bullet-alist
  ;;       '(("TODO" . 9744)
  ;;         ("WAIT" . 9744)
  ;;         ("DONE" . 9745)
  ;;         ("CANC" . 9745)))
  (setq org-superstar-todo-bullet-alist
        '(("TODO" . 9744)
          ("WAIT" . 9744)
          ("DONE" . 9744)
          ("CANC" . 9744)))
  (set-face-attribute 'org-superstar-leading nil :foreground "#42444a"))  ;;   "#42444a"

(use-package org-table
  :defer t
  :config
  (setq org-table-convert-region-max-lines 9999))

(use-package org-table-sticky-header
  :after (org)
  :delight (org-table-sticky-header-mode "Tsh")  ;; \u24C4t OTSH "\u24C9"
  :hook (org-mode . org-table-sticky-header-mode)) ;; must be set before org-sticky-header-mode, maybe orgtbl-show-header can also be used

(use-package org-tempo  ;; expand <s to a src block, ...
  :after (org))

(use-package ob-core
  :defer t
  :hook (org-babel-after-execute . org-redisplay-inline-images)
  :config
  (setq org-babel-inline-result-wrap "%s")     ;; default "=%s="
  (setq org-confirm-babel-evaluate nil)        ;; no "Evaluate this gnuplot code block on your system? (y or n)"
  
  ;; also used in preamble
  (defmacro by-backend (&rest body)
    "BODY is one or more plist element.
The key of plist elements is one of the following lisp symbols:
html, latex, ascii, or t (meaning all other cases).  If BODY is
nil the return value is nil"
    `(case org-export-current-backend ,@body))

  ;; obsolete function
  (defalias 'if-latex 'by-backend)
  (make-obsolete 'if-latex 'by-backend "2020.09.07")
  (advice-add 'if-latex :before
              (lambda (&rest r)
                "Warning: Function `if-latex' is obsolete.
Probably used inside an org file for a src block and/or for an org export.
Updating an old preamble.org should remove this warning."
                (message "Warning: Function `if-latex' is obsolete.
Probably used inside an org file for a src block and/or for an org export.
Updating an old preamble.org should remove this warning."))
              '((name . "obsolete")))

  ;; TODO: still useful?
  (defun svg-fname (filename)
    (concat filename (by-backend
                      (latex "_light")
                      (article-latex "_light")
                      (t "_dark"))
            ".svg")))

(use-package ob-async   ;; https://melpa.org/#/ob-async execute src blocks async, insert in block header (without argument) :async
  :after (org))

(use-package ob-csharp
  :after (org-contrib))

(use-package ob-ditaa
  :defer t
  :config
  ;; org-ditaa-jar-path (car (directory-files "/usr/share/java/ditaa" 'full "[.]*.jar" #'file-newer-than-file-p))
  ;; config to change from a ditaa.jar file to a ditaa executable file
  ;; org-babel-ditaa-java-cmd ""                   ; default is "java". set to "" because system ditaa executable includes java
  ;; org-babel-default-header-args:ditaa           ; default is ((:results . "file") (:exports . "results") (:java . "-Dfile.encoding=UTF-8"))
  ;; '((:results . "file")
  ;;   (:exports . "results"))
  ;; org-ditaa-jar-option ""                       ; default is "-jar". set to "" because system ditaa executable includes -jar
  ;; org-ditaa-jar-path (concat "" (executable-find "ditaa"))
  ;; TODO: find file e.g. (shell-command "cat `which ditaa`") or (shell-command "ls /usr/share/java/ditaa")
  (setq org-ditaa-jar-path "/usr/share/java/ditaa/ditaa-0.11.jar"))

(use-package ob-gnuplot
  :defer t
  :config
  ;; gnuplot config for own org export projects, used in preamble
  (defvar gnuplot-init-light "reset ; \
theme_type = 'light' ; \
set border lc rgb 'black' ; \
set title textcolor 'black' ; \
set xtics textcolor rgb 'black' ; \
set ytics textcolor rgb 'black' ; \
set xlabel textcolor rgb 'black' ; \
set ylabel textcolor rgb 'black' ; \
set zlabel textcolor rgb 'black' ; \
set key textcolor rgb 'black' ; \
set linetype 1 lc rgb '#0071bc' lw 2 pt 5 ; \
set linetype 2 lc rgb '#d85218' lw 2 pt 5 ; \
set linetype 3 lc rgb '#ecb01f' lw 2 pt 5 ; \
set linetype 4 lc rgb '#7d2e8d' lw 2 pt 5 ; \
set linetype 5 lc rgb '#76ab2f' lw 2 pt 5 ; \
set linetype 6 lc rgb '#4cbded' lw 2 pt 5 ; \
set linetype 7 lc rgb '#a1132e' lw 2 pt 5 ; \
filter(x,min,max) = (x >= min && x <= max) ? x : 1/0 ; \
set datafile separator '\\t'  # treat empty fields in a org-table as 'missing' rather than 'bad' (ignoring, shifting column) ")
  (defvar gnuplot-init-dark "reset ; \
theme_type = 'dark' ; \
set border lc rgb '#cccccc' ; \
set title textcolor '#cccccc' ; \
set xtics textcolor rgb '#cccccc' ; \
set ytics textcolor rgb '#cccccc' ; \
set xlabel textcolor rgb '#cccccc' ; \
set ylabel textcolor rgb '#cccccc' ; \
set zlabel textcolor rgb '#cccccc' ; \
set key textcolor rgb '#cccccc' ; \
set linetype 1 lc rgb '#0060ad' lw 2 pt 5 ; \
set linetype 2 lc rgb '#dd181f' lw 2 pt 5 ; \
set linetype 3 lc rgb '#9356a6' lw 2 pt 5 ; \
set linetype 4 lc rgb '#4d92cc' lw 2 pt 5 ; \
set linetype 5 lc rgb '#cc5279' lw 2 pt 5 ; \
set linetype 6 lc rgb '#76ab2f' lw 2 pt 5 ; \
set linetype 7 lc rgb '#ecb01f' lw 2 pt 5 ; \
filter(x,min,max) = (x >= min && x <= max) ? x : 1/0 ; \
set datafile separator '\\t'  # treat empty fields in a org-table as 'missing' rather than 'bad' (ignoring, shifting column) ")
  
  (defun gpl-file (filename)
    "\
FILENAME: the file name

returns: file name with extension for the org src header :file
- for LaTeX export it is set to: FILENAME.tikz
- for other export it is set to: FILENAME.svg

usage: #+HEADER: :file (gpl-file \"ledger-income\")

See also: http://www.gnuplot.info/docs_5.2/Gnuplot_5.2.pdf#section*.519
"
    ;;(concat filename (by-backend (latex ".tex") (t ".svg")) )
    (concat filename (by-backend (latex ".tikz") (article-latex ".tikz") (t ".svg")) )
    ;;(by-backend (latex "") (t (concat filename ".svg")))
    )
  (defun gpl-term (lsize osize)
    "\
LSIZE: latex export size
OSIZE: other export size

returns: term settings for the org src gnuplot header :term
- for LaTeX export it is set to: lua tikz size LSIZE color colortext
- for other export it is set to: svg size OSIZE mouse standalone background '#11000000'

usage: #+HEADER: :term (gpl-term \"15cm,12cm\" \"380,300\")
"
    (concat
     ;;(by-backend (latex "epslatex size ") (t "svg size "))
     (by-backend (latex "lua tikz size ") (article-latex "lua tikz size ") (t "svg size "))
     (by-backend (latex lsize) (article-latex lsize) (t osize))
     (by-backend (latex " color") (article-latex " color") (t " mouse standalone background '#11000000'"))))
  )

(use-package ob-latex
  :defer t
  :config
  ;; tikz config for own org export projects
  (defun tpl-file (filename)
    "\
FILENAME: the file name

returns: file name with extension for the org src header :file
- for LaTeX export it is set to: nil
- for other export it is set to: FILENAME.svg

usage: #+HEADER: :file (tpl-file \"ledger-income\")
"
    (by-backend (latex nil)
                (article-latex nil)
                (t (concat filename ".svg"))))
  (defun tpl-results ()
    "\
TikZ

returns: result type for the org src header :results
- for LaTeX export it is set to: raw
- for other export it is set to: raw file

usage: #+HEADER: :results (tpl-results)
"
    (by-backend (latex "raw")
                (article-latex "raw")
                (t "raw file")))

  ;; overwrite so svg is not combiled by `org-babel-latex-tex-to-pdf'
  ;; but like html with `org-babel-latex-htlatex' and
  ;; `org-babel-latex-htlatex-packages'. htlatex uses pdflatex
  (defun org-babel-execute:latex (body params)
    "Execute a block of Latex code with Babel.
  This function is called by `org-babel-execute-src-block'."
    (setq body (org-babel-expand-body:latex body params))
    (if (cdr (assq :file params))
        (let* ((out-file (cdr (assq :file params)))
         (extension (file-name-extension out-file))
         (tex-file (org-babel-temp-file "latex-" ".tex"))
         (border (cdr (assq :border params)))
         (imagemagick (cdr (assq :imagemagick params)))
         (im-in-options (cdr (assq :iminoptions params)))
         (im-out-options (cdr (assq :imoutoptions params)))
         (fit (or (cdr (assq :fit params)) border))
         (height (and fit (cdr (assq :pdfheight params))))
         (width (and fit (cdr (assq :pdfwidth params))))
         (headers (cdr (assq :headers params)))
         (in-buffer (not (string= "no" (cdr (assq :buffer params)))))
         (org-latex-packages-alist
          (append (cdr (assq :packages params)) org-latex-packages-alist)))
          (cond
           ((and (string-suffix-p ".png" out-file) (not imagemagick))
            (let ((org-format-latex-header
       (concat org-format-latex-header "\n"
         (mapconcat #'identity headers "\n"))))
        (org-create-formula-image
               body out-file org-format-latex-options in-buffer)))
     ;; ((string= "svg" extension)
     ;;  (with-temp-file tex-file
     ;;    (insert (concat (funcall org-babel-latex-preamble params)
     ;;  	    (mapconcat #'identity headers "\n")
     ;;  	    (funcall org-babel-latex-begin-env params)
     ;;  	    body
     ;;  	    (funcall org-babel-latex-end-env params))))
     ;;  (let ((tmp-pdf (org-babel-latex-tex-to-pdf tex-file)))
     ;;          (let* ((log-buf (get-buffer-create "*Org Babel LaTeX Output*"))
     ;;                 (err-msg "org babel latex failed")
     ;;                 (img-out (org-compile-file
     ;;                     tmp-pdf
     ;;                           (list org-babel-latex-pdf-svg-process)
     ;;                           extension err-msg log-buf)))
     ;;            (shell-command (format "mv %s %s" img-out out-file)))))
           ((string-suffix-p ".tikz" out-file)
      (when (file-exists-p out-file) (delete-file out-file))
      (with-temp-file out-file
        (insert body)))
     ((and (or (string= "html" extension) (string= "svg" extension))   ;; CHANGED from only html to html and svg
           (executable-find org-babel-latex-htlatex))
      ;; TODO: this is a very different way of generating the
      ;; frame latex document than in the pdf case.  Ideally, both
      ;; would be unified.  This would prevent bugs creeping in
      ;; such as the one fixed on Aug 16 2014 whereby :headers was
      ;; not included in the SVG/HTML case.
      (with-temp-file tex-file
        (insert (concat
           "\\documentclass[preview]{standalone}
  \\def\\pgfsysdriver{pgfsys-tex4ht.def}
  "
           (mapconcat (lambda (pkg)
            (concat "\\usepackage" pkg))
          org-babel-latex-htlatex-packages
          "\n")
           (if headers
         (concat "\n"
           (if (listp headers)
               (mapconcat #'identity headers "\n")
             headers) "\n")
             "")
           "\\begin{document}"
           body
           "\\end{document}")))
      (when (file-exists-p out-file) (delete-file out-file))
      (let ((default-directory (file-name-directory tex-file)))
        (shell-command (format "%s %s" org-babel-latex-htlatex tex-file)))
      (cond
       ((file-exists-p (concat (file-name-sans-extension tex-file) "-1.svg"))
        (if (string-suffix-p ".svg" out-file)
      (progn
        (shell-command "pwd")
        (shell-command (format "mv %s %s"
             (concat (file-name-sans-extension tex-file) "-1.svg")
             out-file)))
          (error "SVG file produced but HTML file requested")))
       ((file-exists-p (concat (file-name-sans-extension tex-file) ".html"))
        (if (string-suffix-p ".html" out-file)
      (shell-command "mv %s %s"
               (concat (file-name-sans-extension tex-file)
                 ".html")
               out-file)
          (error "HTML file produced but SVG file requested")))))
     ((or (string= "pdf" extension) imagemagick)
      (with-temp-file tex-file
        (require 'ox-latex)
        (insert
         (org-latex-guess-inputenc
          (org-splice-latex-header
           org-format-latex-header
           (delq
      nil
      (mapcar
       (lambda (el)
         (unless (and (listp el) (string= "hyperref" (cadr el)))
           el))
       org-latex-default-packages-alist))
           org-latex-packages-alist
           nil))
         (if fit "\n\\usepackage[active, tightpage]{preview}\n" "")
         (if border (format "\\setlength{\\PreviewBorder}{%s}" border) "")
         (if height (concat "\n" (format "\\pdfpageheight %s" height)) "")
         (if width  (concat "\n" (format "\\pdfpagewidth %s" width))   "")
         (if headers
       (concat "\n"
         (if (listp headers)
             (mapconcat #'identity headers "\n")
           headers) "\n")
           "")
         (if fit
       (concat "\n\\begin{document}\n\\begin{preview}\n" body
         "\n\\end{preview}\n\\end{document}\n")
           (concat "\n\\begin{document}\n" body "\n\\end{document}\n"))))
            (when (file-exists-p out-file) (delete-file out-file))
      (let ((transient-pdf-file (org-babel-latex-tex-to-pdf tex-file)))
        (cond
         ((string= "pdf" extension)
          (rename-file transient-pdf-file out-file))
         (imagemagick
          (org-babel-latex-convert-pdf
           transient-pdf-file out-file im-in-options im-out-options)
          (when (file-exists-p transient-pdf-file)
      (delete-file transient-pdf-file)))
         (t
          (error "Can not create %s files, please specify a .png or .pdf file or try the :imagemagick header argument"
           extension))))))
          nil) ;; signal that output has already been written to file
      body))
  ;; end of ob-latex
  )

(use-package ob-python
  :defer t
  :config
  (defun mpl-var (filename)
    "\
FILENAME: the file name

returns: file name varible with extension for the org src header :var
- for LaTeX export it is set to: FILENAME.pgf
- for other export it is set to: FILENAME.svg

usage: #+HEADER: :var fname=(mpl-var \"ledger-income\")
"
    (concat filename (by-backend (latex ".pgf") (article-latex ".pgf") (t ".svg"))))
  (defun mpl-prologue (&optional mplstyle)
    "\
Matplotlib

returns: style settings for a org src python matplotlib code block
- for LaTeX export it is not set.
- for other export it is set to load kpfonts and my.mplstyle.
  Optional Argument MPLSTYLE:
  - my (default)
  - my-tex (uses latex to render fonts)

usage:
  #+HEADER: :prologue (mpl-prologue)
  #+HEADER: :prologue (mpl-prologue \"my-tex\")
"
    (by-backend (latex "")
                (article-latex "")
                (t (format "\
import matplotlib.font_manager
kpfonts = matplotlib.font_manager.findSystemFonts(fontpaths=['%s'])
[matplotlib.font_manager.fontManager.addfont(i) for i in kpfonts]

import matplotlib.style
matplotlib.style.reload_library()

import matplotlib.pyplot as plt
styles = plt.style.core.read_style_directory('%s')
plt.style.core.update_nested_dict(plt.style.library, styles)
try:
  plt.style.use('%s')
except:
  pass
"
                           (concat config-dir "scripts/fonts")
                           (concat config-dir "scripts/matplotlib-stylelib")
                           (or mplstyle "my"))))))

(use-package ol-notmuch
  :after (org))

(use-package ox
  :defer t
  :config
  ;; https://orgmode.org/manual/Advanced-Export-Configuration.html
  ;; https://en.wikibooks.org/wiki/LaTeX/Internationalization
  ;; (defun my-org-export-filter-hyphen-shy (text backend info)
  ;;   "Convert \"- to &shy; in HTML export."
  ;;   (when (org-export-derived-backend-p backend 'html)
  ;;     (replace-regexp-in-string "\"-" "&shy;" text))
  ;;   )
  ;; (defun my-org-export-filter-hyphen-hard (text backend info)
  ;;   "Convert \"= to - in HTML export."
  ;;   (when (org-export-derived-backend-p backend 'html)
  ;;     (replace-regexp-in-string "\"=" "-" text))
  ;;   )
  ;; (add-to-list 'org-export-filter-body-functions
  ;;              'my-org-export-filter-hyphen-shy)
  ;; (add-to-list 'org-export-filter-body-functions
  ;;              'my-org-export-filter-hyphen-hard)
  ;;(add-to-list 'org-export-filter-latex-fragment-functions
  ;;             'my-org-export-filter-hyphen-shy)
  (setq org-export-with-smart-quotes t)  ;; OPTIONS keyword, e.g., "’:t".
  (setq org-export-with-sub-superscripts '{})  ;; OPTIONS keyword, e.g., "^:{}".
  
  ;; http://permalink.gmane.org/gmane.emacs.orgmode/93971
  ;; https://emacs.stackexchange.com/questions/30575/adding-latex-newpage-before-a-heading/30892
  (defun my-org-headline-string-element (headline backend info)
    "Return the org element representation of an element. Won't work on ~verb~/=code=-only headers"
    (let ((prop-point (next-property-change 0 headline)))
      (if prop-point (plist-get (text-properties-at prop-point headline) :parent))))
  (defun my-org-latex-ensure-clearpage (headline backend info)
    "Insert a clearpage before the heading if property clearpage is non-nil.
Uses function `my-org-headline-string-element'"
    (when (org-export-derived-backend-p backend 'latex)
      (let ((elmnt (my-org-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
               'my-org-latex-ensure-clearpage))

(use-package ox-extra
  :after (org)  ;; defer t is not enough bc/ ox-extra is not loaded by default
  :config
  ;; https://emacs.stackexchange.com/questions/9492/is-it-possible-to-export-content-of-subtrees-without-their-headings
  ;; https://emacs.stackexchange.com/questions/44018/use-package-ensure-not-working-package-downloaded-but-gives-warning-and-skips-c
  (ox-extras-activate '(ignore-headlines)))  ;; see in variable `ox-extras'

(use-package ox-html
  :defer t  ;; will be loaded via `org-export-backends' see above inside `org'
  :config
  (setq org-html-doctype "html5")
  (setq org-html-html5-fancy t)
  (setq org-html-validation-link nil)          ;; remove the "Validate" link at the bottom of the page
  (setq org-html-mathjax-options
        '((path "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML")
          ;;(path "/js/MathJax-master/MathJax.js?config=TeX-AMS_HTML")
          (scale "100")
          (align "center")
          (font "TeX")
          (linebreaks "false")
          (autonumber "AMS")
          (indent "0em")
          (multlinewidth "85%")
          (tagindent ".8em")
          (tagside "right")))                  ;; #+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Euler
  ;; http://docs.mathjax.org/en/latest/input/tex/macros/
  (setq org-html-mathjax-template "<script type=\"text/x-mathjax-config\">
    MathJax.Ajax.config.path[\"Contrib\"] = \"https://cdn.mathjax.org/mathjax/contrib\";
    MathJax.Hub.Register.StartupHook(\"TeX Jax Ready\",function () {
        MathJax.Hub.Insert(MathJax.InputJax.TeX.Definitions.macros,{
            cancel: [\"Extension\",\"cancel\"],
            bcancel: [\"Extension\",\"cancel\"],
            xcancel: [\"Extension\",\"cancel\"],
            cancelto: [\"Extension\",\"cancel\"]
        });
    });
    MathJax.Hub.Config({
        extensions: [\"[Contrib]/siunitx/siunitx.js\"],
        displayAlign: \"%ALIGN\",
        displayIndent: \"%INDENT\",

        \"HTML-CSS\": { scale: %SCALE,
                        linebreaks: { automatic: \"%LINEBREAKS\" },
                        webFont: \"%FONT\"
                       },
        SVG: {scale: %SCALE,
              linebreaks: { automatic: \"%LINEBREAKS\" },
              font: \"%FONT\"},
        NativeMML: {scale: %SCALE},
        TeX: { equationNumbers: {autoNumber: \"%AUTONUMBER\"},
               MultLineWidth: \"%MULTLINEWIDTH\",
               TagSide: \"%TAGSIDE\",
               TagIndent: \"%TAGINDENT\",
               Macros: {
                         ti: [\"{_\\\\text{#1}}\",1],
                         ho: [\"{^\\\\text{#1}}\",1],
                         field: [\"\\\\mathbb{#1}\",1],
                         fC: \"{\\\\field{C}}\",
                         fN: \"{\\\\field{N}}\",
                         fR: \"{\\\\field{R}}\",
                         fQ: \"{\\\\field{Q}}\",
                         fI: \"{\\\\field{I}}\",
                         fZ: \"{\\\\field{Z}}\",
                         qed: \"{\\\\blacksquare}\",
                         T: \"{\\\\mathrm{T}}\",
                         dif: \"{\\\\,\\\\mathop{}\\\\!\\\\mathrm{d}}\",
                         norm: [\"{\\\\lVert{}#1\\\\rVert}\",1],
                         abs: [\"{\\\\lvert{}#1\\\\rvert}\",1],
                         corresponds: \"{{\\\\kern0em\\\\raise{.5ex}{\\\\Large\\\\hat{}}\\\\kern-.73em\\\\raise{-.2ex}{=}}\\\\ }\",
                         dt: [\"{\\\\overset{{\\\\large\\\\bf{}.}}{#1}}\",1],
                         ddt: [\"{\\\\overset{{\\\\large\\\\bf{}.\\\\hspace{-0.1ex}.}}{#1}}\",1],
                         Eval: [\"{\\\\left.#1\\\\phantom{\\\\Big|}\\\\!\\\\!\\\\right\\\\rvert_{#2}^{#3}}\",3],
                         tensor: [\"{\\\\mathbf{#1}}\",1],
                         tensorI: [\"{\\\\underline{\\\\mathbf{#1}}}\",1],
                         tensorII: [\"{\\\\underline{\\\\underline{\\\\mathbf{#1}}}}\",1],
                         tensorIII: [\"{\\\\underset{\\\\raise{.5ex}{\\\\Large\\\\tilde{\\\\small{}3}}}{\\\\mathbf{#1}}}\",1],
                         tensorIV: [\"{\\\\underset{\\\\raise{.5ex}{\\\\Large\\\\tilde{\\\\small{}4}}}{\\\\mathbf{#1}}}\",1],
                         tensori: [\"{\\\\overrightarrow{#1}}\",1],
                         tensorii: [\"{\\\\overleftrightarrow{#1}}\",1],
                         tensoriii: [\"{\\\\overrightarrow{\\\\overleftrightarrow{#1}}}\",1],
                         tensoriv: [\"{\\\\overleftrightarrow{\\\\overleftrightarrow{#1}}}\",1],
                         rank: \"{\\\\mathop{\\\\mathrm{rank}}}\",
                         tr: \"{\\\\mathop{\\\\mathrm{tr}}}\",
                         dev: \"{\\\\mathop{\\\\mathrm{dev}}}\",
                         var: \"{\\\\mathop{\\\\mathrm{var}}}\",
                         grad: \"{\\\\mathop{\\\\mathrm{grad}}}\",
                         divergence: \"{\\\\mathop{\\\\mathrm{div}}}\",
                         rot: \"{\\\\mathop{\\\\mathrm{rot}}}\",
                         diag: \"{\\\\mathop{\\\\mathrm{diag}}}\",
                         adjungate: \"{\\\\mathop{\\\\mathrm{adj}}}\",
                         EUR: \"{\\\\text{€}}\"
               }
             }
});
</script>
<script type=\"text/javascript\"
        src=\"%PATH\"></script>")
  )

(use-package ox-latex
  :defer t  ;; will be loaded via `org-export-backends' see above inside `org'
  :config
  (setq org-latex-compiler "lualatex")   ;; %latex in org-latex-pdf-process
  (setq org-latex-bib-compiler "biber")  ;; %bib in org-latex-pdf-process
  (setq org-latex-pdf-process
        (if (executable-find "latexmk")
            '("latexmk -f -pdf -%latex -shell-escape -interaction=nonstopmode -output-directory=%o %f")
          (cond ((string-equal org-latex-compiler "lualatex")
                 '("lualatex --interaction=nonstopmode --output-directory=%o %f"
                   "biber %b"
                   "lualatex --interaction=nonstopmode --output-directory=%o %f"
                   "lualatex --interaction=nonstopmode --output-directory=%o %f"))
                ((string-equal org-latex-compiler "pdflatex")
                 '("%latex -shell-escape -interaction nonstopmode -output-directory %o %f"
                   "%bib %b"
                   "%latex -shell-escape -interaction nonstopmode -output-directory %o %f"
                   "%latex -shell-escape -interaction nonstopmode -output-directory %o %f"))
                (t '("%latex -interaction nonstopmode -output-directory %o %f"
                     "%latex -interaction nonstopmode -output-directory %o %f"
                     "%latex -interaction nonstopmode -output-directory %o %f")))))
  (setq org-latex-listings t)
  (setq org-latex-listings-options
        '(("numbers" "left")
          ;; ("captionpos" "t")  ;; not working, see org-latex-caption-above
          ))
  (setq org-latex-caption-above '(table src-block))
  (setq org-latex-logfiles-extensions
        '("aux" "bcf" "blg" "fdb_latexmk" "fls" "figlist" "idx" "log" "nav" "out"
          "ptc" "run.xml" "snm" "toc" "vrb" "xdv"
          "lof" "lot" "lol"
          "bbl"              ;; biblatex package, biber; biblatex auxiliary file
          "ist"              ;; glossaries package; makeindex style file
          "alg" "acr" "acn"  ;; glossaries package; acronyms
          "glg" "gls" "glo"  ;; glossaries package; glossary
          "los.glg" "los.gls" "los.glo"  ;; glossaries package; list of symbols
          ;; "nlg" "not" "ntn"  ;; glossaries package; notation
          "idx" "ind" "ilg"  ;; imakeidx package; index
          ;; minitoc
          "mtc"              ;; minitoc package; temp file
          "maf"              ;; minitoc package; list of discardable auxiliary files used by minitoc
          "mtc0"             ;; minitoc package; table of contents for a chapter
          ))
  
  ;; overwrite org ox-latex
  (defun org-latex--inline-image (link info)
     "Return LaTeX code for an inline image.
LINK is the link pointing to the inline image.  INFO is a plist
used as a communication channel."
     (let* ((parent (org-export-get-parent-element link))
	    (path (let ((raw-path (org-element-property :path link)))
		    (if (not (file-name-absolute-p raw-path)) raw-path
		      (expand-file-name raw-path))))
	    (filetype (file-name-extension path))
	    (caption (org-latex--caption/label-string parent info))
	    (caption-above-p (org-latex--caption-above-p link info))
	    ;; Retrieve latex attributes from the element around.
	    (attr (org-export-read-attribute :attr_latex parent))
	    (float (let ((float (plist-get attr :float)))
		     (cond ((string= float "wrap") 'wrap)
			   ((string= float "sideways") 'sideways)
			   ((string= float "multicolumn") 'multicolumn)
			   ((and (plist-member attr :float) (not float)) 'nonfloat)
			   ((or float
			        (org-element-property :caption parent)
			        (org-string-nw-p (plist-get attr :caption)))
			    'figure)
			   (t 'nonfloat))))
	    (placement
	     (let ((place (plist-get attr :placement)))
	       (cond
	        (place (format "%s" place))
	        ((eq float 'wrap) "{l}{0.5\\textwidth}")
	        ((eq float 'figure)
	         (format "[%s]" (plist-get info :latex-default-figure-position)))
	        (t ""))))
	    (center
	     (if (plist-member attr :center) (plist-get attr :center)
	       (plist-get info :latex-images-centered)))
	    (comment-include (if (plist-get attr :comment-include) "%" ""))
	    ;; It is possible to specify width and height in the
	    ;; ATTR_LATEX line, and also via default variables.
	    (width (cond ((plist-get attr :width))
		         ((plist-get attr :height) "")
		         ((eq float 'wrap) "0.48\\textwidth")
		         (t (plist-get info :latex-image-default-width))))
	    (height (cond ((plist-get attr :height))
		          ((or (plist-get attr :width)
			       (memq float '(figure wrap))) "")
		          (t (plist-get info :latex-image-default-height))))
	    (options (let ((opt (or (plist-get attr :options)
				    (plist-get info :latex-image-default-option))))
		       (if (not (string-match "\\`\\[\\(.*\\)\\]\\'" opt)) opt
		         (match-string 1 opt))))
	    image-code)
       (if (member filetype '("tikz" "pgf"))
	   ;; For tikz images:
	   ;; - use \input to read in image file.
	   ;; - if options are present, wrap in a tikzpicture environment.
	   ;; - if width or height are present, use \resizebox to change
	   ;;   the image size.
	   (progn
	     (setq image-code (format "\\input{%s}" path))
	     (when (org-string-nw-p options)
	       (setq image-code
		     (format "\\begin{tikzpicture}[%s]\n%s\n\\end{tikzpicture}"
			     options
			     image-code)))
	     (when (or (org-string-nw-p width) (org-string-nw-p height))
	       (setq image-code (format "\\resizebox{%s}{%s}{%s}"
				        (if (org-string-nw-p width) width "!")
				        (if (org-string-nw-p height) height "!")
				        image-code))))
         ;; For other images:
         ;; - add width and height to options.
         ;; - include the image with \includegraphics.
         (when (org-string-nw-p width)
	   (setq options (concat options ",width=" width)))
         (when (org-string-nw-p height)
	   (setq options (concat options ",height=" height)))
         (let ((search-option (org-element-property :search-option link)))
           (when (and search-option
                      (equal filetype "pdf")
                      (string-match-p "\\`[0-9]+\\'" search-option)
                      (not (string-match-p "page=" options)))
             (setq options (concat options ",page=" search-option))))
         (setq image-code
	       (format "\\includegraphics%s{%s}"
		       (cond ((not (org-string-nw-p options)) "")
			     ((string-prefix-p "," options)
			      (format "[%s]" (substring options 1)))
			     (t (format "[%s]" options)))
		       path))
         (when (equal filetype "eps")
	   (setq image-code (replace-regexp-in-string "^\\\\includegraphics\\[.+\\]"
						      "\\input"
						      image-code
						      nil t))
	   (setq image-code (replace-regexp-in-string "\\.eps}"
						      ".tex}"
						      image-code
						      nil t)))
         (when (equal filetype "svg")
	   (setq image-code (replace-regexp-in-string "^\\\\includegraphics"
						      "\\includesvg"
						      image-code
						      nil t))
	   (setq image-code (replace-regexp-in-string "\\.svg}"
						      "}"
						      image-code
						      nil t)))
         )
       ;; Return proper string, depending on FLOAT.
       (pcase float
         (`wrap (format "\\begin{wrapfigure}%s
%s%s
%s%s
%s\\end{wrapfigure}"
		        placement
		        (if caption-above-p caption "")
		        (if center "\\centering" "")
		        comment-include image-code
		        (if caption-above-p "" caption)))
         (`sideways (format "\\begin{sidewaysfigure}
%s%s
%s%s
%s\\end{sidewaysfigure}"
			    (if caption-above-p caption "")
			    (if center "\\centering" "")
			    comment-include image-code
			    (if caption-above-p "" caption)))
         (`multicolumn (format "\\begin{figure*}%s
%s%s
%s%s
%s\\end{figure*}"
			       placement
			       (if caption-above-p caption "")
			       (if center "\\centering" "")
			       comment-include image-code
			       (if caption-above-p "" caption)))
         (`figure (format "\\begin{figure}%s
%s%s
%s%s
%s\\end{figure}"
		          placement
		          (if caption-above-p caption "")
		          (if center "\\centering" "")
		          comment-include image-code
		          (if caption-above-p "" caption)))
         ((guard center)
          (format "\\begin{center}
%s%s
%s\\end{center}"
	          (if caption-above-p caption "")
	          image-code
	          (if caption-above-p "" caption)))
         (_
          (concat (if caption-above-p caption "")
	          image-code
	          (if caption-above-p caption "")))))))

(use-package ox-md
  :defer t)  ;; will be loaded via `org-export-backends' see above inside `org'

(use-package ox-publish
  :defer t
  :config
  (setq org-publish-timestamp-directory (concat user-cache-directory "org-timestamps/"))
  (setq org-publish-project-alist my-org-publish-project-alist))

(use-package ox-reveal
  :defer t  ;; will be loaded via `org-export-backends' see above inside `org'
  :config
  ;; #+REVEAL_EXTRA_CSS:
  (setq org-reveal-extra-css (concat "file://" (expand-file-name config-dir) "scripts/flipcard/flipcard.css"))  ;; multiple files seperated with \n
  ;; #+REVEAL_POSTAMBLE:
  (setq org-reveal-postamble (replace-regexp-in-string "\n" "" (concat "<script>" (org-reveal--read-file (concat (expand-file-name config-dir) "scripts/flipcard/flipcard.js")) "\n</script>")))  ;; only one line!
  (setq org-reveal-root (concat "file://" (expand-file-name config-dir) "scripts/reveal.js"))
  (setq org-reveal-single-file t))

(use-package ox-tufte   ;; https://melpa.org/#/ox-tufte
  :defer t  ;; will be loaded via `org-export-backends' see above inside `org'
  :config
  (defun org-tufte-src-block (src-block _contents info)
     "Transcode a SRC-BLOCK element from Org to HTML.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information."
     (if (org-export-read-attribute :attr_html src-block :textarea)
         (org-html--textarea-block src-block)
       (let* ((lang (org-element-property :language src-block))
	      (code (org-html-format-code src-block info))
	      (label (let ((lbl (and (org-element-property :name src-block)
				     (org-export-get-reference src-block info))))
		       (if lbl (format " id=\"%s\"" lbl) "")))
	      (klipsify  (and  (plist-get info :html-klipsify-src)
                               (member lang '("javascript" "js"
					      "ruby" "scheme" "clojure" "php" "html")))))
         (if (not lang) (format "<pre class=\"example\"%s>\n%s</pre>" label code)
	   (format "<div class=\"org-src-container\">\n%s%s\n</div>"
		   ;; Build caption.
		   (let ((caption (org-export-get-caption src-block)))
		     (if (not caption) ""
		       (let ((listing-number
			      (format
			       "<span class=\"listing-number\">%s </span>"
			       (format
			        (org-html--translate "Listing %d:" info)
			        (org-export-get-ordinal
			         src-block info nil #'org-html--has-caption-p)))))
		         (format "<label class=\"org-src-name\">%s%s</label>"
			         listing-number
			         (org-trim (org-export-data caption info))))))
		   ;; Contents.
		   (if klipsify
		       (format "<pre><code class=\"src src-%s\"%s%s>%s</code></pre>"
			       lang
			       label
			       (if (string= lang "html")
				   " data-editor-type=\"html\""
			         "")
			       code)
		     (format "<pre class=\"src src-%s\"%s>%s</pre>"
                             lang label code))))))))

;; Allows you to edit entries directly from org-brain-visualize
(use-package polymode
  :defer t
  :config
  (add-hook 'org-brain-visualize-mode-hook #'org-brain-polymode))


(provide 'org-settings)
;;; org-settings.el ends here
