UP | HOME

How to do X with Emacs Org-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 Mon> <2020-11-13 Fri>  
Task 0 2 <2020-11-03 Tue> [2020-11-05 Thu] Al
Task 1 1 <2020-11-05 Thu> <2020-11-06 Fri> Bo
Task 2 3 <2020-11-05 Thu> [2020-11-10 Tue] Ca
Task 3 2 <2020-11-06 Fri> <2020-11-10 Tue> Ca
Task 4 2 <2020-11-06 Fri> <2020-11-06 Fri> Bo
Task 5 1 <2020-11-10 Tue> <2020-11-10 Tue> Bo
Task 6 1 <2020-11-11 Wed> <2020-11-12 Thu> Bo
Task 7 2 <2020-11-09 Mon> <2020-11-10 Tue> Al
Task 8 1 <2020-11-12 Thu> <2020-11-12 Thu> Al
Task 9 1 <2020-11-06 Fri> <2020-11-09 Mon> Al
Task 10 1 <2020-11-12 Thu> <2020-11-13 Fri> Bo
Task 11 1 <2020-11-13 Fri> <2020-11-13 Fri>  

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

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