The wonderful Emacs Org mode is the basis for the largest part of my personal knowledge management system.

However, as I’ve mentioned before, mobile accessibility is its weakest point.

In this post, I’m going to explain my possibly unconventional new solution to the important requirement I mentioned in that note-taking post:

Ideally, I would have easy access to my complete org database and any related files.

As you can easily deduce from the title of this post, the solution involves converting all of my org database into docx files, with the main motivation that the Dropbox mobile app has excellent support both for the fast previewing and searching through the contents of docx files, while it has none of that sort of support for .org or .md files.

The desired outcome: An example

Let’s say I needed to find my Org mode notes about the TDBGrid in the Lazarus IDE on my phone.

In the Dropbox app, searching for TDBGrid finds the relevant docx instantaneously:

Previewing the docx file, still in the Dropbox app, shows me exactly the code example and context I needed to see, reasonably rendered as well:

For reference, this is what the source note looks like in full-fat Emacs Org mode:

The above search-and-preview flow is not possible on the source Org mode files with the Dropbox app on mobile.

What is not shown here, is that you also get a navigable document structure view (based on the headings) right in the dropbox app preview.

CMakeLists for the Pandoc conversion of a nested directory of files

At the highest level, I wanted to use Pandoc to convert each org file, along with any embedded images, to docx.

(I started with HTML, but Dropbox previewing of that was inconsistent, search did not seem to work that well, and there was no heading navigation.)

I knew that I wanted a Makefile to do this conversion, so that pandoc would only be applied on org files that had not yet been converted, or had their most recent version converted. This saves a tremendous amount of time when updating the docx repo.

I also knew that I would prefer not to write the Makefile by hand, and so I reached for CMake.

A great number of browser tabs later, I came up with the following CMakeLists.txt, which now lives in the same directory as my org-file hierarchy (the directory is named pkb4000 which lives in my dropbox):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# cmake to convert recursively a directory of .org and .md files to .docx using pandoc
cmake_minimum_required(VERSION 3.16)
project(pkb4000-html)

# we'll store all docx output filenames in here so we can setup a custom target
# that depends on them
set(ALL_OUTPUTS "")

# because of RELATIVE, orgfiles are relative to CMAKE_CURRENT_SOURCE_DIR
# (we're converting both orgfiles and markdown files)
file(GLOB_RECURSE ORGFILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/*.org" "${CMAKE_CURRENT_SOURCE_DIR}/*.md")
foreach(orgfile ${ORGFILES})
  set(OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/${orgfile}.docx)
  # get directory part so that we can create output subdir part if required
  get_filename_component(OUTPUT_DIR ${OUTPUT_FILE} DIRECTORY)
  # for each org / md file, create a md/org -> docx rule
  add_custom_command(
    OUTPUT ${OUTPUT_FILE}
    # VERBATIME so that e.g. ( is correctly escaped
    VERBATIM COMMAND mkdir -p ${OUTPUT_DIR} && cd "${CMAKE_CURRENT_SOURCE_DIR}" && pandoc --standalone --number-sections -o "${OUTPUT_FILE}" "${CMAKE_CURRENT_SOURCE_DIR}/${orgfile}"
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${orgfile}
  )
  list(APPEND ALL_OUTPUTS ${OUTPUT_FILE})

endforeach(orgfile)

# finally setup default target that will build all docx files
add_custom_target(bleh ALL DEPENDS ${ALL_OUTPUTS})

To generate the Makefile, I did:

1
2
3
4
5
6
# pkb4000 contains the source org files and linked images
# docx-pkb4000 is a newly created dir at the same level as pkb4000
# this is what cmake calls an out-of-source build
mkdir docx-pkb4000
cd docx-pkb4000
cmake ../pkb4000

From here on out, a simple make inside of docx-pkb4000 will update the docx files to the latest org files.

If you add new org files, you wil have to re-run cmake ../pkb4000 from the docx-pkb4000 directory before running make again.

Add to cron for automatic updates

Thanks to a suggestion by ZH from work, I’ve added the folllowing to my personal crontab to update the docx notes archive every 30 minutes, taking into account that new org files have possibly been added:

1
*/30 * * * * cd /home/cpbotha/Dropbox/notes/docx-pkb4000 && /usr/bin/cmake . && /usr/bin/make

Conclusion

For the first time, this definitely satisfies my requirement of having easy access to my complete Org mode database and any related files, through the Dropbox app’s great support for the full text searching and previewing of DOCX files.

Having the docx files available on all of the systems where I have dropbox installed, has proven to be a convenience by itself. System search tools generally also do a better job of previewing docx files than Org mode files.

This mobile accessibility is indeed limited to viewing (which was the largest part of my need on the phone), and does not cater for adding new multimedia content.

For that, I have become quite interested in Dropbox Paper’s capabilities, but that is a topic for another post.