# -*- 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.')