appendorgheading

Append a new Org mode heading to an existing Org mode file


Keywords
org, mode, orgmode, CLI, logging, shell
License
GPL-3.0
Install
pip install appendorgheading==2020.6.2.1

Documentation

appendorgheading

This script appends Org mode headings to any existing Org mode file which are plain text files with the extension .org.

You can use this script to generate arbitrary Org mode headings. It’s mainly a wrapper script for the function orgformat() of orgformat.

Why

The author is using this script to log things to an errors.org file which is part of his Org mode agenda:

example_script.sh >out.log 2>&1 || \
         appendorgheading --output errors.org \
                          --filecontent out.log \
                          --level 2 \
                          --keyword "TODO"
                          --title "example_script: some error occurred" \
                          --daily

When this example_script.sh returns an exit status which is not zero, appendorgheading is adding a new heading to the file errors.org at level 2 (two asterisks) with the title “example_script: some error occurred”.

Using the --daily parameter, there is a time-stamp attached which re-occurs on a daily basis. This looks similar to <2019-12-29 Sun 16:01 +1d> which causes this entry to appear on every agenda so that it gets recognized and hopefully resolved. On resolving the issue, the author deletes (or achives) this heading.

If these parameters are always the same, you can use the configuration file (see section below) to store the default values. Using this, you can reduce the example call above to:

example_script.sh >out.log 2>&1 || appendorgheading 

The errors.org gets a new heading that looks like:

** TODO example_script: some error occurred

#+BEGIN_EXAMPLE
<This is the content of 
the file out.log.>
#+END_EXAMPLE

Of course, there are much more command line parameters to add tags, priorities, and other Org mode heading properties. See section “Usage” below.

Installation

This tool needs Python 3 to be installed.

You can install this script either via pip which is the recommended way. Or you can install it using the source code, e.g., by cloning the GitHub repository.

Install via pip: pip install appendorgheading

First Steps

After installing, I’d recommend you to read the help screen appendorgheading -h or the Usage section below in order to get an overview on the possibilities.

Then, you’d like to do generate a stub of a configuration file via:

appendorgheading --generateconfigfile testconfig.ini

Alternatively, you can use as many command line options as you like when generating the configuration file similar to:

appendorgheading --generateconfigfile testconfig.ini --output ~/org/errors.org --level 2 --daily

This will populate the generated configuration file with provided settings.

If you do like the generated configuration file, rename and move it to one of the two locations in order to activate the configuration file:

  1. file .appendorgheading in the current working directory OR
  2. in your home directory: ~/.appendorgheading

Provided settings do have following priorities:

  1. command line options
  2. .appendorgheading in the current working directory
  3. ~/.appendorgheading

In other words: command line options always overrule any configuration file settings. Therefore, you can put your default settings in a configuration file and overrule via command line parameters whenever necessary to keep the average command line parameters at a minimum just as in the “Why” section.

If you are unsure, you can always use the test option --dryrun which doesn’t change any files at all and tells you what would happen.

Usage

usage: appendorgheading [-h] [--output <FILE.ORG>]
                        [--level <level>] [--keyword <TODO>]
                        [--priority "PRIO"]
                        [--title "HEADING TITLE"]
                        [--tags "STRING WITH TAGS"]
                        [--scheduled "STRING WITH DATE/TIME-STAMP"]
                        [--deadline "STRING WITH DATE/TIME-STAMP"]
                        [--properties "KEY1:VALUE1; KEY2:VALUE2"]
                        [--section "STRING"]
                        [--filecontent <FILE>] [--daily]
                        [--dryrun] [--generateconfigfile <FILE>]
                        [-v] [-q] [--version]

This tool appends Org mode formatted headings to existing Org mode files.

The optional configuration file ".appendorgheading" can be placed:
1. the current directory  ... OR ...
2. the home directory ("~/.appendorgheading")
Command line parameters override configuration file entries.

A typical use-case for this script is logging:
The author is using this to log events to some kind of 'errors.org' which is part
of his Org mode agenda.

  example_script.sh >out.log 2>&1 || appendorgheading --filecontent "out.log"

This will use the default settings from your configuration file and log to the
defined Org mode file only if "example_script.sh" has an exit status not equal
to zero. It also appends the content of the log file for further analysis.

optional arguments:
  -h, --help            show this help message and exit
  --output <FILE.ORG>   Path to the Org mode file to append to
  --level <level>       The heading level (number of asterisks): 1, 2, 3, ...
  --keyword <TODO>      TODO keyword such as "TODO", "ERROR", ...
  --priority "PRIO"     Priority indicator such as "A" or "C"
  --title "HEADING TITLE"
                        Title of the heading
  --tags "STRING WITH TAGS"
                        One or more tags (if multiple: in quotes, separated by
                        spaces)
  --scheduled "STRING WITH DATE/TIME-STAMP"
                        An Org mode date- or time-stamp such as "<2019-12-29
                        Sun>" which is added as SCHEDULED
  --deadline "STRING WITH DATE/TIME-STAMP"
                        An Org mode date- or time-stamp such as "<2019-12-29
                        Sun>" which is added as DEADLINE
  --properties "KEY1:VALUE1; KEY2:VALUE2"
                        A string with key-value pairs. Colons separate keys
                        from values, semicolons separate the key-value-pairs.
  --section "STRING"    This is used as the section text or body of the
                        heading.
  --filecontent <FILE>  Path to a filename whose content gets appended to the
                        section body within an EXAMPLE block
  --daily               Add a time-stamp that is recurring on a daily basis
  --dryrun              Enable dryrun mode: just simulate what would happen,
                        do not modify files
  --generateconfigfile <FILE>
                        Path to a filename which gets created or overwritten
                        with a configuration file that contains default values
                        or the values given by the parameters
  -v, --verbose         Enable verbose mode
  -q, --quiet           Enable quiet mode
  --version             Display version and exit

:copyright: (c) by Karl Voit <tools@Karl-Voit.at>
:license: GPL v3 or any later version
:URL: https://github.com/novoid/appendorgheading
:bugreports: via github or <tools@Karl-Voit.at>
:version: 2019-12-30
·

Examples

Additional to the example from the “Why”-section above, here are some other use-cases for this tool:

Checking for file age

The author is generating an ical/ics-file via cron. If this is failing somehow because of Emacs tripping over some problematic Org mode data, this ics file gets old without noticing. Since I am using this to update a calendar server, this is a silent issue.

With appendorgheading, I can add a check for this using the shell script appendorgheading-if-file-too-old.sh:

#!/bin/sh
set -o errexit

FILENAME="${1}"
MAXDAYS="${2}"
HELPTEXT="${3}"

OLD=`stat -c %Y "${FILENAME}"`
NOW=`date +%s`
DIFFDAYS=$(( ($NOW - $OLD) / (60*60*24) ))
DIFFHRS=$(( ($NOW - $OLD) / (60*60) ))

[ $DIFFDAYS -gt $MAXDAYS ] && /usr/local/bin/appendorgheading --title "\"${FILENAME}\" is older than $DIFFDAYS days" \
        --quiet \
        --section "File is $DIFFHRS hours old: $(ls -la ${FILENAME})\n\n${HELPTEXT}"
exit 0
#end

My invocation command looks like:

appendorgheading-if-file-too-old.sh /home/vk/.emacs.d/var/export/agenda-export.ics 0 "check with id:2019-11-19-HOWTO-check-and-fix-Org-agenda-radicale"

Changelog

  • 2019.12.30.1: first version
  • 2020.06.02.1: added command line option for --nodaily to override configuration file preference

How to Thank Me

I’m glad you like my tools. If you want to support me:

  • Send old-fashioned postcard per snailmail - I love personal feedback!
  • Send feature wishes or improvements as an issue on GitHub
  • Create issues on GitHub for bugs
  • Contribute merge requests for bug fixes
  • Check out my other cool projects on GitHub

Local Variables