From 115a5c705dd05fe2e1339fd28a0925a4c70b09e9 Mon Sep 17 00:00:00 2001 From: William Minchin Date: Tue, 29 Jul 2014 00:43:26 -0600 Subject: [PATCH] Allow export to Pelican formatted Markdown --- jrnl/cli.py | 4 ++-- jrnl/exporters.py | 51 +++++++++++++++++++++++++++++++++-------------- jrnl/util.py | 1 - 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/jrnl/cli.py b/jrnl/cli.py index af60bbe4..1c7ed480 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -42,8 +42,8 @@ def parse_args(args=None): exporting = parser.add_argument_group('Export / Import', 'Options for transmogrifying your journal') exporting.add_argument('--short', dest='short', action="store_true", help='Show only titles or line containing the search tags') exporting.add_argument('--tags', dest='tags', action="store_true", help='Returns a list of all tags and number of occurences') - exporting.add_argument('--export', metavar='TYPE', dest='export', choices=['text', 'txt', 'markdown', 'md', 'json'], help='Export your journal. TYPE can be json, markdown, or text.', default=False, const=None) - exporting.add_argument('-o', metavar='OUTPUT', dest='output', help='Optionally specifies output file when using --export. If OUTPUT is a directory, exports each entry into an individual file instead.', default=False, const=None) + exporting.add_argument('--export', metavar='TYPE', dest='export', choices=['text', 'txt', 'markdown', 'md', 'json', 'pelican', 'pelican-md'], help='Export your journal. TYPE can be json, markdown, text, or pelican.', default=False, const=None) + exporting.add_argument('-o', metavar='OUTPUT', dest='output', help='Optionally specifies output file when using --export. If OUTPUT is a directory, exports each entry into an individual file instead (required for pelican exports).', default=False, const=None) exporting.add_argument('--encrypt', metavar='FILENAME', dest='encrypt', help='Encrypts your existing journal with a new password', nargs='?', default=False, const=None) exporting.add_argument('--decrypt', metavar='FILENAME', dest='decrypt', help='Decrypts your journal and stores it in plain text', nargs='?', default=False, const=None) exporting.add_argument('--edit', dest='edit', help='Opens your editor to edit the selected entries.', action="store_true") diff --git a/jrnl/exporters.py b/jrnl/exporters.py index 71919f34..104833c6 100644 --- a/jrnl/exporters.py +++ b/jrnl/exporters.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python # encoding: utf-8 from __future__ import absolute_import @@ -65,10 +65,23 @@ def to_txt(journal): """Returns the complete text of the Journal.""" return journal.pprint() +def to_pelican(entry): + """Returns a markdown representation of the Journal with Pelican formatted + front matter""" + out = '' + out = out + 'Title: ' + entry.title + '\n' + out = out + 'Date: ' + str(entry.date) + '\n' + if entry.tags: + # drop tag symbol + out = out + 'Tags: ' + ', '.join([tag[1:] for tag in entry.tags]) + '\n' + out += '\n' + out += entry.body + return out + def export(journal, format, output=None): """Exports the journal to various formats. - format should be one of json, txt, text, md, markdown. + format should be one of json, txt, text, md, markdown, pelican, pelican-md. If output is None, returns a unicode representation of the output. If output is a directory, exports entries into individual files. Otherwise, exports to the given output file. @@ -78,37 +91,45 @@ def export(journal, format, output=None): "txt": to_txt, "text": to_txt, "md": to_md, - "markdown": to_md + "markdown": to_md, + "pelican": to_pelican, + "pelican-md": to_pelican } if format not in maps: - return u"[ERROR: can't export to '{0}'. Valid options are 'md', 'txt', and 'json']".format(format) + return u"[ERROR: can't export to '{0}'. Valid options are 'md', 'txt', 'json', and 'pelican']".format(format) if output and os.path.isdir(output): # multiple files return write_files(journal, output, format) else: - content = maps[format](journal) - if output: - try: - with codecs.open(output, "w", "utf-8") as f: - f.write(content) - return u"[Journal exported to {0}]".format(output) - except IOError as e: - return u"[ERROR: {0} {1}]".format(e.filename, e.strerror) + if format is ("pelican" or "pelican-md"): + return u"Pelican exports must be to a directory." else: - return content + content = maps[format](journal) + if output: + try: + with codecs.open(output, "w", "utf-8") as f: + f.write(content) + return u"[Journal exported to {0}]".format(output) + except IOError as e: + return u"[ERROR: {0} {1}]".format(e.filename, e.strerror) + else: + return content def write_files(journal, path, format): """Turns your journal into separate files for each entry. - Format should be either json, md or txt.""" + Format should be either json, md, txt or pelican.""" make_filename = lambda entry: e.date.strftime("%Y-%m-%d_{0}.{1}".format(slugify(u(e.title)), format)) for e in journal.entries: - full_path = os.path.join(path, make_filename(e)) if format == 'json': content = json.dumps(e.to_dict(), indent=2) + "\n" elif format in ('md', 'markdown'): content = e.to_md() elif format in ('txt', 'text'): content = e.__unicode__() + elif format in ('pelican', 'pelican-md'): + make_filename = lambda entry: e.date.strftime("%Y-%m-%d_{0}.{1}".format(slugify(u(e.title)), 'md')) + content = to_pelican(e) + full_path = os.path.join(path, make_filename(e)) with codecs.open(full_path, "w", "utf-8") as f: f.write(content) return u"[Journal exported individual files in {0}]".format(path) diff --git a/jrnl/util.py b/jrnl/util.py index b06113c2..4449abe5 100644 --- a/jrnl/util.py +++ b/jrnl/util.py @@ -145,7 +145,6 @@ def int2byte(i): This is equivalent to chr() in Python 2 and bytes((i,)) in Python 3.""" return chr(i) if PY2 else bytes((i,)) - def byte2int(b): """Converts a byte to an integer. This is equivalent to ord(bs[0]) on Python 2 and bs[0] on Python 3."""