3

I have been using Day One for a while but I dislike it being Mac only. I have a capture template in orgmode that creates new journal entries in a tree.

Example:

*2015

**2015-11 November.

***2015-11-2 Monday

**** My journal entry.

Day One can export to markdown. The format is like this:

Date: June 2, 2010 at 11:11 PM Location: My location, City, Country Weather: 45° Clear

Text entry.

What would be the best way to I import this into my orgmode journal?

0
1

I ended up doing this because dayone exports with tabs:

\t\Date:\t

Replace with:

***

Then creating years and moving stuff manually. Titles don't have the same exact format that orgmode journal creates but who cares.

0

You can do this quickly with regex search & replace, M-C %. Replace ^Date: with *** to create your headlines, and repeat for other elements as necessary. Since you'll only likely do this once, a few rounds of search & replace is probably going to be faster than writing code.

2
  • But this wont create the datetree right?
    – Jason Mirk
    Nov 2 '15 at 18:02
  • No, you would have to insert the Year and Month headings yourself. Since there is no indicator in the Day One text you could convert directly, your choices are either to do this by hand, or write up a custom search & replace function in elisp.
    – Tyler
    Nov 2 '15 at 18:20
0

My elisp is too bad to make the converter inside emacs, but I whipped up a Ruby script to do it for you.

Converts a Day One plain text export (Journal.txt) into org-mode journal format. It does ...

  • Markdown image conversion from to [[thepath.jpg]]
  • Extraction of images from the front of an entry; moves it right after the property drawer.
  • Creation of nested year/month/day date sections (see example below)

That means you get a nested outline like this

* 2020
** 2020-03 March
*** 2020-03-14 Saturday
**** Here's a diary entry imported from Day One.
:PROPERTIES:
:CREATED: [2020-03-14 Sat 14:33]
:END_PROPERTIES:
**** And another one from the same day.
:PROPERTIES:
:CREATED: [2020-03-14 Sat 19:12]
:END_PROPERTIES:
** 2020-06 June
*** 2020-06-22 Monday
**** Year, month, and day sections are created automatically.
:PROPERTIES:
:CREATED: [2020-06-22 Mon 08:06]
:END_PROPERTIES:

Script source

See the public Gist or the following code: https://gist.github.com/DivineDominion/f7be383776bef5a57a4a812fabc4e8b7

#!/usr/bin/env ruby
#
#  convert_dayone_to_org.rb
#  Copyright © 2020 Christian Tietze. All rights reserved. Distributed under the MIT License.
# 
#  TODOs:
#  - changing the image directory name during import using an option
#  - changing the hash-based image file names to date-time format
#
#  Usage:
#
#   ./convert_dayone_to_org.rb Journal.txt output.org

require "date"

input, output, *rest = ARGV
if input.nil?
  STDERR.puts "Usage: #{__FILE__} DAYONE_INPUT_PATH ORG_OUTPUT_PATH"
  STDERR.puts "Missing input file path"
  exit 1
elsif output.nil?
  STDERR.puts "Usage: #{__FILE__} DAYONE_INPUT_PATH ORG_OUTPUT_PATH"
  STDERR.puts "Missing output file path"
  exit 1
end

File.open(output, "w") do |out|
  # Cached values to make sub-headings
  year = nil
  month = nil
  day = nil
  props = {}
  File.readlines(input).each do |line|
    if /\A\t(?<key>\w+):\t(?<value>.*+)$/ =~ line
      # Collect metadata in `props` dictionary
      case key
      when "Date"
        date = DateTime.parse(value)
        props["Created"] = date.strftime("[%Y-%m-%d %a %H:%M]")
        # Convert date lines to new entries in org

        # Output:  "* 2020"
        if year != date.year
          out.puts "* #{date.year}"
          year = date.year
          month = nil
        end

        # Output:  "** 2020-03 March"
        if month != date.month
          out.puts "** #{date.strftime("%Y-%m %B")}"
          month = date.month
        end

        # Output:  "*** 2020-03-12 Thursday"
        this_day = date.strftime("%Y-%m-%d %A")
        if day != this_day
          out.puts "*** #{this_day}"
        end
      else
        props[key] = value
      end
    elsif !props.empty?
      # Produce entry title and metadata
      if line.strip.empty?
        # Skip empty line separator after metadata
      else
        # Add entry heading, handling leading entry images
        cached_image = nil
        if /\A!\[]\((?<path>.+)\)(?<rest>.*)$/ =~ line
          cached_image = "[[./#{path}]]"
          out.puts "**** #{rest}"
        else
          out.puts "**** #{line}"
        end

        # Append property drawer
        out.puts ":PROPERTIES:"
        out.puts(props.map { |key, value| ":" + key.upcase.to_s + ":  " + value.to_s }
                      .join("\n"))
        out.puts ":END_PROPERTIES:"
        props = {}

        if !cached_image.nil?
          out.puts ""
          out.puts cached_image
        end
      end
    else
      line = line.gsub(/!\[\]\((.+)\)/) { "[[./#{$1}]]" }
      out.puts line
    end
  end
end

(Also posted more details on my blog for this https://christiantietze.de/posts/2020/10/export-day-one-journal-to-org-mode/)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.