119 lines
4.3 KiB
Python
119 lines
4.3 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
# Copyright © 2012-2013 Puneeth Chaganti and others.
|
||
|
|
||
|
# Permission is hereby granted, free of charge, to any
|
||
|
# person obtaining a copy of this software and associated
|
||
|
# documentation files (the "Software"), to deal in the
|
||
|
# Software without restriction, including without limitation
|
||
|
# the rights to use, copy, modify, merge, publish,
|
||
|
# distribute, sublicense, and/or sell copies of the
|
||
|
# Software, and to permit persons to whom the Software is
|
||
|
# furnished to do so, subject to the following conditions:
|
||
|
#
|
||
|
# The above copyright notice and this permission notice
|
||
|
# shall be included in all copies or substantial portions of
|
||
|
# the Software.
|
||
|
#
|
||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||
|
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||
|
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||
|
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||
|
# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
|
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
|
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
""" Implementation of compile_html based on Emacs Org-mode.
|
||
|
|
||
|
You will need to install emacs and org-mode (v8.x or greater).
|
||
|
|
||
|
"""
|
||
|
|
||
|
from __future__ import unicode_literals
|
||
|
import io
|
||
|
import os
|
||
|
from os.path import abspath, dirname, join
|
||
|
import shlex
|
||
|
import subprocess
|
||
|
|
||
|
try:
|
||
|
from collections import OrderedDict
|
||
|
except ImportError:
|
||
|
OrderedDict = dict # NOQA
|
||
|
|
||
|
from nikola.plugin_categories import PageCompiler
|
||
|
from nikola.utils import req_missing, makedirs
|
||
|
|
||
|
# v6 compat
|
||
|
try:
|
||
|
from nikola.utils import write_metadata
|
||
|
except ImportError:
|
||
|
write_metadata = None # NOQA
|
||
|
|
||
|
|
||
|
class CompileOrgmode(PageCompiler):
|
||
|
""" Compile org-mode markup into HTML using emacs. """
|
||
|
|
||
|
name = "orgmode"
|
||
|
|
||
|
def compile(self, source, dest, is_two_file=True, post=None, lang=None):
|
||
|
"""Compile the source file into HTML and save as dest."""
|
||
|
makedirs(os.path.dirname(dest))
|
||
|
try:
|
||
|
command = [
|
||
|
'emacs', '--batch',
|
||
|
'-l', join(dirname(abspath(__file__)), 'init.el'),
|
||
|
'--eval', '(nikola-html-export "{0}" "{1}")'.format(
|
||
|
abspath(source), abspath(dest))
|
||
|
]
|
||
|
|
||
|
# Dirty walkaround for this plugin to run on Windows platform.
|
||
|
if os.name == 'nt':
|
||
|
command[5] = command[5].replace("\\", "\\\\")
|
||
|
|
||
|
subprocess.check_call(command)
|
||
|
with io.open(dest, 'r', encoding='utf-8') as inf:
|
||
|
output, shortcode_deps = self.site.apply_shortcodes(
|
||
|
inf.read(), extra_context={'post': post})
|
||
|
with io.open(dest, 'w', encoding='utf-8') as outf:
|
||
|
outf.write(output)
|
||
|
if post is None:
|
||
|
if shortcode_deps:
|
||
|
self.logger.error(
|
||
|
"Cannot save dependencies for post {0} (post unknown)",
|
||
|
source)
|
||
|
else:
|
||
|
post._depfile[dest] += shortcode_deps
|
||
|
except OSError as e:
|
||
|
import errno
|
||
|
if e.errno == errno.ENOENT:
|
||
|
req_missing(['emacs', 'org-mode'],
|
||
|
'use the orgmode compiler', python=False)
|
||
|
except subprocess.CalledProcessError as e:
|
||
|
raise Exception('''Cannot compile {0} -- bad org-mode configuration (return code {1})
|
||
|
The command is {2}'''.format(source, e.returncode, ' '.join(shlex.quote(arg) for arg in e.cmd)))
|
||
|
|
||
|
def create_post(self, path, content=None, onefile=False, is_page=False, **kw):
|
||
|
"""Create post file with optional metadata."""
|
||
|
metadata = OrderedDict()
|
||
|
metadata.update(self.default_metadata)
|
||
|
metadata.update(kw)
|
||
|
makedirs(os.path.dirname(path))
|
||
|
|
||
|
with io.open(path, "w+", encoding="utf-8") as fd:
|
||
|
if onefile:
|
||
|
fd.write("#+BEGIN_COMMENT\n")
|
||
|
if write_metadata:
|
||
|
fd.write(write_metadata(metadata))
|
||
|
else:
|
||
|
for k, v in metadata.items():
|
||
|
fd.write('.. {0}: {1}\n'.format(k, v))
|
||
|
fd.write("#+END_COMMENT\n")
|
||
|
fd.write("\n\n")
|
||
|
|
||
|
if content:
|
||
|
fd.write(content)
|
||
|
else:
|
||
|
fd.write('Write your post here.')
|