UP | HOME

How to do X with Emacs Org-Mode

(dark mode)

Emacs Org mode keeps me organized. Here I plan to incrementally gather tipps.


PDF (drucken)

full-page images per page for printing via latex eport

Task: create a PDF with full-width images for printing.

#+latex_header: \usepackage[margin=0.0cm]{geometry}
#+options: toc:nil


# ## upside image ##
#+latex: \noindent
#+attr_latex: :width 0.9999\textwidth :height 0.9999\textheight :options keepaspectratio=true,angle=90
file:portrait.jpg


# ## rotated image ##
#+latex: \noindent
#+attr_latex: :width 0.9999\textwidth :height 0.9999\textheight :options keepaspectratio=true
file:landscape.jpg


# ## two images per page ##
#+latex: \noindent
#+attr_latex: :width 0.9999\textwidth :height 0.495\textheight :options keepaspectratio=true
file:landscape.jpg

#+latex: \noindent
#+attr_latex: :width 0.9999\textwidth :height 0.495\textheight :options keepaspectratio=true
file:landscape.jpg


# ## keep some space around the images 

#+latex: \noindent
#+attr_latex: :width 0.98\textwidth :height 0.98\textheight :options keepaspectratio=true
file:portrait.jpg

Now just export with C-c C-e l p (export to pdf). (the 0.9999 height and width prevent LaTeX from skipping pages)

To turn these into a gallery with 4x4 images per page to cut out the images, you can use pdfnup:

pdfnup --nup 4x4 --no-landscape foo.pdf
# creates foo-nup.pdf

agenda-and-todo: my most important planning tool

When I open my Emacs, I hit F12.

screenshot-20210826103308-width600.png

This is what keeps me organized — at home as well as at work. As you can see with the high scheduled count, it isn't perfect, but whenever I skip it, I lose focus. A lifesaver at work, staying ahead of important tasks at home.

It’s a custom agenda combined with kanban.el and optimized TODO states.

Put this into your ~/.emacs.d/init.el to replicate it:

;; KDE: show custom agenda with kanban via f12:
(with-eval-after-load 'org
  (setq org-agenda-custom-commands
        '(("o" "Agenda and TODOs"
           ((agenda)
            (tags-todo "-notodo-TERMIN" ((org-agenda-block-separator ?-)))
                (tags "KANBAN" ((org-agenda-block-separator ?-)
                            (org-agenda-compact-blocks nil)
                            (org-agenda-overriding-header ""))))))))

;; from https://www.emacswiki.org/emacs/TransposeWindows solution by Robert Bost
(defun rotate-windows (arg)
  "Rotate your windows; with prefix argument to rotate the other direction"
  (interactive "P")
  (if (not (> (count-windows) 1))
      (message "You can't rotate a single window!")
    (let* ((rotate-times (prefix-numeric-value arg))
           (direction (if (or (< rotate-times 0) (equal arg '(4)))
                          'reverse 'identity)))
      (dotimes (_ (abs rotate-times))
        (dotimes (i (- (count-windows) 1))
          (let* ((w1 (elt (funcall direction (window-list)) i))
                 (w2 (elt (funcall direction (window-list)) (+ i 1)))
                 (b1 (window-buffer w1))
                 (b2 (window-buffer w2))
                 (s1 (window-start w1))
                 (s2 (window-start w2))
                 (p1 (window-point w1))
                 (p2 (window-point w2)))
            (set-window-buffer-start-and-point w1 b2 s2 p2)
            (set-window-buffer-start-and-point w2 b1 s1 p1)))))))

(defun my/org-agenda-show-kanban ()
  (interactive)
  (save-excursion
    (search-forward ":KANBAN:")
    (org-agenda-goto)
    (org-narrow-to-subtree)
    (show-all)
    (fit-window-to-buffer)
    (widen)
    (recenter-top-bottom 0)))

(defun agenda-and-todo ()
  (interactive)
  (org-agenda nil "o")
  (delete-other-windows)
  (my/org-agenda-show-kanban)
  (rotate-windows 1))
;;      systemsettings shortcuts: map f12 to
;;        emacsclient -e '(progn (show-frame)(agenda-and-todo))'
(global-set-key (kbd "<f12>") 'agenda-and-todo)

To make it look like the screenshot, also set some options in the org-file:

#+STARTUP: overview
# TAG TERMIN is excluded from the Kanban table
#+TAGS: WOHNUNG(w) RAUS(r) SONST(s) LESEN(l) KANBAN(k) 1w6(1) FAMILIE(f) TERMIN(t)
#+STARTUP: hidestars logdone
#+SEQ_TODO: ❢ ☯ ⧖ | ✔ DEFERRED
# logdone adds a DONE timestamp when switching from a TODO (before |)
# to a DONE keyword (after |)
# State with (!) behind it means, add a timestamp when switching to that.
# See http://orgmode.org/manual/Tracking-TODO-state-changes.html

|   |   |   |
|---+---+---|
|   |   |   |
|   |   |   |
|   |   |   |
#+TBLFM: @1='(kanban-headers $#)::@2$1..@>$>='(kanban-zero @# $# "-TERMIN" 'file)

If you use this, the following could also come in handy:

;; KDE: update all agenda kanban tables with C-S-f12 (ctrl-shift f12)
(defun kanban-update-all ()
  (interactive)
  (cl-loop for i in org-agenda-files do
           (with-current-buffer (find-file-noselect i)
             (save-excursion ;; avoid changing the position in the agenda files
               (beginning-of-buffer)
               (while (search-forward "='(kanban-" nil t)
                 (org-ctrl-c-ctrl-c))))))
;;      systemsettings shortcuts: map control shift f12 to
;;        emacsclient -e '(progn (show-frame)(kanban-update-all))'
(global-set-key (kbd "C-S-<f12>") 'kanban-update-all)

create a simple gantt-chart from a table with Gnuplot

Gantt-Charts make it easy to grasp project organization tasks at a glance. If you only need smaller projects with limited scope and 4-6 participants, it is viable to create them directly from an org-mode table.

gantt-out.png

All data is in the following Table:

Task Effort Start End Who
Time available 1 <2020-11-02 Mo> <2020-11-13 Fr>  
Task 0 2 <2020-11-03 Di> [2020-11-05 Do] Al
Task 1 1 <2020-11-05 Do> <2020-11-06 Fr> Bo
Task 2 3 <2020-11-05 Do> [2020-11-10 Di] Ca
Task 3 2 <2020-11-06 Fr> <2020-11-10 Di> Ca
Task 4 2 <2020-11-06 Fr> <2020-11-06 Fr> Bo
Task 5 1 <2020-11-10 Di> <2020-11-10 Di> Bo
Task 6 1 <2020-11-11 Mi> <2020-11-12 Do> Bo
Task 7 2 <2020-11-09 Mo> <2020-11-10 Di> Al
Task 8 1 <2020-11-12 Do> <2020-11-12 Do> Al
Task 9 1 <2020-11-06 Fr> <2020-11-09 Mo> Al
Task 10 1 <2020-11-12 Do> <2020-11-13 Fr> Bo
Task 11 1 <2020-11-13 Fr> <2020-11-13 Fr>  

the time available row ensures that the whole project-duration is shown. You need to set the start and end dates manually: Hit C-c . to enter the calendar and select the date.

The parsing is done by the following code:

# http://gnuplot.sourceforge.net/demo_5.1/gantt.html
OneMonth = strptime("%m","2")
OneWeek = strptime("%U","2")
OneDay = strptime("%d","2")
timeformat = "%Y-%m-%d %a"
T(N) = timecolumn(N,timeformat)

set xdata time
set format x "%a\n%d\n%b\n'%y"
set xtics OneDay nomirror
set xtics scale 2, 0.5
set mxtics 7

skiptorow=2
set yrange [(skiptorow-2):] reverse
set ytics nomirror

unset key
set title "{/=15 My Project}"
set grid x y
set border 3
set style arrow 1 nohead filled size screen 0.02, 15 fixed lt 3 lw 8

plot DATA using (T(3)) : ($0) : (T(4)-T(3)) : (0.0) : yticlabel(1) with vector as 1

You might have to add gnuplot to your active languages:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((gnuplot . t)))

More complex Gantt with plantuml

If you need something more complex, you can go to the full plantuml DSL. Example:

@startgantt
saturday are closed
sunday are closed
' see https://plantuml.com/gantt-diagram
Project starts at 2021-04-26
[Configuration] as [C] on {DEV1:50%} lasts 1 day
note bottom
  description
end note
[Implementation] as [I] on {DEV2} lasts 3 days
note bottom
  in multiple
  lines
end note
[I] starts at [C]'s end with green bold link
{DEV2} is off on 2021-04-30
@endgantt
my-complex-project.png

The full source of these examples with the org-mode sourceblocks is available in my website's source-code.

Projects to export gantt from the org-mode tree

export to markdown and latex

(require 'ox-md)
#+begin_export markdown
# foo
__bar__
#+end_export
#+begin_export latex
\section{foo}
\textbf{bar}
#+end_export
*bar*

[2021-10-18 Mo]

run org-capture from commandline

emacs -nw -e org-capture

I call this in the shell via CRTL-r capture ENTER: Search backwards for the last command with capture.

[2021-11-11 Do]

How I stay ahead of tasks with org-mode

I found that org-mode is the only organization tool for which using the tool actually reduces the time I need for organization. That works by taking notes in org-mode, too, and keeping it simple.

I also found that whenever I skip organizing in org-mode, I lose focus and time used (lost?) for tasks extends a lot.

The basics of my setup are:

Custom starting point: agenda-with-kanban

A function to show the agenda it besides the Kanban table. I start each day and after each larger break by hitting F12. It shows me the agenda and entry points into my work. This enables me to stay focussed.

One planning file

I have a single file for all my tasks. That keeps working surprisingly long. Once a year or so it needs some cleanup to become faster again.

Kanban Table at the top

I have a kanban table. It shows as most important information the tasks I am doing right now. If I am doing more than three work-tasks at the same time, it’s warning sign that I’m becoming inefficient. With this I start every day in org-mode by clicking on the link of the project from the kanban table to get to its notes (which I also track in org-mode). See https://www.draketo.de/light/english/free-software/el-kanban-org-tablehttps://hg.sr.ht/~arnebab/kanban.el

Capture tasks for Projects

Projects have as many tasks as I need to track. At work they are usually Stories (3-5 days). Nowadays I create new tasks by using org-capture templates with one template per larger project and one for bugs, but I used to just use two templates (which might be a better fit for you):

  • (i) task to start immediately and
  • (l) task to start later

Setup

(with-eval-after-load 'org
  (setq org-agenda-custom-commands
        '(("o" "Agenda and TODOs"
           ((agenda)
            (tags-todo "-notodo-TERMIN" ((org-agenda-block-separator ?-)))
                (tags "KANBAN" ((org-agenda-block-separator ?-)
                            (org-agenda-compact-blocks nil)
                            (org-agenda-overriding-header ""))))))))
  (defun my/org-agenda-show-kanban ()
  (interactive)
  (save-excursion
    (search-forward ":KANBAN:") ;; uses the KANBAN tag
    (org-agenda-goto)
    (org-narrow-to-subtree)
    (show-all)
    (fit-window-to-buffer)
    (widen)
    (recenter-top-bottom 0)))

(defun agenda-and-todo ()
  (interactive)
  (org-agenda nil "o")
  (delete-other-windows)
  (my/org-agenda-show-kanban)
;;      desktop systemsettings shortcuts: map f12 to
;;        emacsclient -e '(progn (show-frame)(agenda-and-todo))'
(global-set-key (kbd "<f12>") 'agenda-and-todo)

[2022-03-01 Di]

Effort in Clocktable and Columns

To track how much time you need for tasks and train to get better at estimating, you can use org-set-effort. I did that at work for a while.

By having the effort in a clocktable I could see progress when needed.

Hitting R in the org-agenda shows the clockreport-mode and you can see the Effort in the agenda by customizing org-agenda-clockreport-parameter-plist (with M-x customize-variable):

(org-agenda-clockreport-parameter-plist
 (quote (:link t :maxlevel 2 :properties ("Effort"))))

For a while I had the clocktable active by default in the org-agenda.

You can also add that to the column-mode (org-columns) to get a quick overview for a file (leave with org-columns-quit). Customize:

(org-columns-default-format
   "%25ITEM %TODO %3PRIORITY %TAGS %17Effort(Estimated Effort){:} %CLOCKSUM")

[2022-03-01 Di]

integrating accounting with ledger into org-mode

If you use ledger-cli for accounting, you can do pretty clever post-processing inside org-mode. Here’s an example that uses –register-format to provide the register results directly as an org-mode table:

#+name: ledger-to-table
#+begin_src elisp :var data=""
(concat "#+name: ledger-results\n"
          data
          "#+tblfm: \n"))
#+end_src

#+header: :post ledger-to-table(*this*)
#+header: :cmdline reg -D --register-format "| [%(format_date(date)) %(payee)] | %(display_account) | %(display_amount) | %(display_total) | \n" --wide --date-format %Y-%m-%d
#+begin_src ledger :results raw
2022-06-15 * py2guile
    Assets:epubli             3.13€
    Income:epubli
#+end_src

This results in output like this (evaluated live on every export of this website):

(concat "#+name: ledger-results\n"
          data
          "#+tblfm: \n"))
2022-06-15 * py2guile
    Assets:epubli             3.13€
    Income:epubli
[2022-06-15 Mi] Assets:epubli 3.13€ 3.13€
[2022-06-15 Mi] Income:epubli -3.13€ 0.00€

To supercharge this, use noweb to re-use your filings for other formats. Set :noweb-ref in the data-block and then use it for other reports. This for example gives todays balance for the different accounts:

#+header: :post ledger-to-table(*this*)
#+header: :cmdline bal --wide --date-format %Y-%m-%d --flat --balance-format "| %(partial_account) | %(display_total) | \n" 
#+begin_src ledger :exports both :noweb no-export :results raw 
{{{ledger-data}}}
#+end_src
{{{ledger-data}}}

This uses direct evaluation and customized noweb-delimiters via:

# Local Variables:
# org-confirm-babel-evaluate: nil
# org-babel-noweb-wrap-start: "{{{"
# org-babel-noweb-wrap-end: "}}}"
# End:

Also see

[2023-02-04 Sa]

Easy signature-block for multiple signatures in org

I’ve long struggled to create simple signature lines, using \hrulefill, \uline and some of the other options.

But all of these didn’t really match what I wanted, so here’s a simpler version for org-mode:

#+latex: \vfill

#+latex_header: \usepackage[ngerman]{babel} % for German-formatted dates
#+latex: \newcommand{\pA}{THE NAME 1}
#+latex: \newcommand{\dA}{\today}
#+latex: \newcommand{\lA}{LOCATION}

#+latex: \newcommand{\pB}{THE NAME 2}
#+latex: \newcommand{\dB}{\today}
#+latex: \newcommand{\lB}{LOCATION}

| @@latex:\pA@@                       | @@latex:\hspace{1cm}@@ | @@latex:\pB@@                       |
|                                     |                        |                                     |
| @@latex:\underline{\phantom{\pA}}@@ |                        | @@latex:\underline{\phantom{\pB}}@@ |
| @@latex:\tiny \dA, \lA@@            |                        | @@latex:\tiny \dB, \lB@@            |

[2023-10-06 Fr]

Include an imagemap with a plantuml diagram

Embed a plantuml diagram with clickable links via simple imagemap.

Code

#+begin_src plantuml :noweb-ref plantuml-imagemap-diagram :file plantuml-imagemap-diagram.png
title Plantuml diagram with Imagemap
hide empty members
hide circle
' scale dpi to be small enough so the image does not get scaled, otherwise the imagemap is broken
skinparam dpi 72
class link [[#plantuml-imagemap-code]] #skyblue
link : to code
link -> example
#+end_src

#+attr_html: :style width:unset;max-width:unset :usemap #plantuml_map
#+RESULTS:
file:plantuml-imagemap-diagram.png

#+html: <div style="visibility: hidden">
#+begin_src plantuml :noweb yes :file plantuml-imagemap-diagram.map :cmdline "-pipemap" :exports results
<<plantuml-imagemap-diagram>>
#+end_src

#+RESULTS:
file:plantuml-imagemap-diagram.map
#+html: </div>

#+begin_src bash :results output html :exports results
cat plantuml-imagemap-diagram.map
#+end_src

This is a quite contrived hack, but it works. Note that the width must be unset to avoid breaking the imagemap coordinates.

Stackoverflow provides several answers to avoid this limitation in case you want responsive images: Responsive Image Map.

I’m using this is Programming Basics: a map of Scheme with Wisp.

[2024-01-10 Mi]

ArneBab 2021-08-23 Mo 00:00 - Impressum - GPLv3 or later (code), cc by-sa (rest)