-
Notifications
You must be signed in to change notification settings - Fork 844
/
Copy pathorg_reader.py
124 lines (93 loc) · 4 KB
/
org_reader.py
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""
Org Reader
==========
Version 1.1.
Relevant Pelican settings:
- ORG_READER_EMACS_LOCATION: Required. Location of Emacs binary.
- ORG_READER_EMACS_SETTINGS: Optional. An absolute path to an Elisp file, to
run per invocation. Useful for initializing the `package` Emacs library if
that's where your Org mode comes from, or any modifications to Org Export-
related variables.
- ORG_READER_BACKEND: Optional. A custom backend to provide to Org. Defaults
to 'html.
To provide metadata to Pelican, the following properties can be defined in
the org file's header:
#+TITLE: The Title Of This BlogPost
#+DATE: 2001-01-01
#+CATEGORY: blog-category
#+AUTHOR: My Name
#+PROPERTY: LANGUAGE en
#+PROPERTY: SUMMARY hello, this is the description
#+PROPERTY: SLUG test_slug
#+PROPERTY: MODIFIED [2015-12-29 Di]
#+PROPERTY: TAGS my, first, tags
#+PROPERTY: TEMPLATE article
#+PROPERTY: SAVE_AS alternative_filename.html
- The TITLE is the only mandatory header property
- Timestamps (DATE and MODIFIED) are optional and can be either a string of
%Y-%m-%d or an org timestamp
- The property names (SUMMARY, SLUG, MODIFIED, TAGS, TEMPLATE, SAVE_AS) can be either
lower-case or upper-case
- The slug is automatically the filename of the Org file, if not explicitly
specified
- It is not possible to pass an empty property to Pelican. For this plugin,
it makes no difference if a property is present in the Org file and left
empty, or if it is not defined at all.
"""
import os
import json
import logging
import subprocess
from pelican import readers
from pelican import signals
ELISP = os.path.join(os.path.dirname(__file__), 'org_reader.el')
LOG = logging.getLogger(__name__)
class OrgEmacsReader(readers.BaseReader):
enabled = True
EMACS_ARGS = ["-Q", "--batch"]
ELISP_EXEC = "(org->pelican \"{0}\" {1})"
file_extensions = ['org']
def read(self, filename):
assert 'ORG_READER_EMACS_LOCATION' in self.settings, \
"No ORG_READER_EMACS_LOCATION specified in settings"
LOG.info("Reading Org file {0}".format(filename))
cmd = [self.settings['ORG_READER_EMACS_LOCATION']]
cmd.extend(self.EMACS_ARGS)
if 'ORG_READER_EMACS_SETTINGS' in self.settings:
cmd.append('-l')
cmd.append(self.settings['ORG_READER_EMACS_SETTINGS'])
backend = self.settings.get('ORG_READER_BACKEND', "'html")
cmd.append('-l')
cmd.append(ELISP)
cmd.append('--eval')
cmd.append(self.ELISP_EXEC.format(filename, backend))
LOG.debug("OrgEmacsReader: running command `{0}`".format(cmd))
json_result = subprocess.check_output(cmd, universal_newlines=True)
json_output = json.loads(json_result)
# get default slug from .org filename
default_slug, _ = os.path.splitext(os.path.basename(filename))
metadata = {'title': json_output['title'] or '',
'date': json_output['date'] or '',
'author': json_output['author'] or '',
'lang': json_output['language'] or '',
'category': json_output['category'] or '',
'slug': json_output['slug'] or default_slug,
'modified': json_output['modified'] or '',
'tags': json_output['tags'] or '',
'save_as': json_output['save_as'] or '',
'summary': json_output['summary'] or '',
'status': json_output['status'] or '',
'template': json_output['template'] or None}
# remove empty strings when necessary
for key in ['save_as', 'modified', 'lang', 'summary']:
if not metadata[key]:
metadata.pop(key)
parsed = {}
for key, value in metadata.items():
parsed[key] = self.process_metadata(key, value)
content = json_output['post']
return content, parsed
def add_reader(readers):
readers.reader_classes['org'] = OrgEmacsReader
def register():
signals.readers_init.connect(add_reader)