diff options
Diffstat (limited to 'site-src/plugins/orgmode')
-rw-r--r-- | site-src/plugins/orgmode/README.md | 46 | ||||
-rw-r--r-- | site-src/plugins/orgmode/__pycache__/orgmode.cpython-36.pyc | bin | 0 -> 3159 bytes | |||
-rw-r--r-- | site-src/plugins/orgmode/conf.py.sample | 8 | ||||
-rw-r--r-- | site-src/plugins/orgmode/init.el | 126 | ||||
-rw-r--r-- | site-src/plugins/orgmode/macros.org | 19 | ||||
-rw-r--r-- | site-src/plugins/orgmode/orgmode.plugin | 15 | ||||
-rw-r--r-- | site-src/plugins/orgmode/orgmode.py | 129 | ||||
-rw-r--r-- | site-src/plugins/orgmode/requirements-nonpy.txt | 2 |
8 files changed, 345 insertions, 0 deletions
diff --git a/site-src/plugins/orgmode/README.md b/site-src/plugins/orgmode/README.md new file mode 100644 index 0000000..eedcc31 --- /dev/null +++ b/site-src/plugins/orgmode/README.md @@ -0,0 +1,46 @@ +This plugin implements an Emacs Org-mode based compiler for Nikola. + +## Setup + +If your emacs does not ship with org-mode (>=8.x), you will have to edit the +`init.el` file supplied with this plugin, and load a newer version of org-mode. + +You will also need to add the orgmode compiler to your list of compilers, and +modify your POSTS & PAGES variables. (See the sample conf file provided.) + +### Syntax highlighting with pygments + +By default, the plugin uses `pygments` for syntax highlighting. You can disable +this by setting `nikola-use-pygments` to `nil` in `init.el` or `conf.el` (see +Customization section below). + +To get proper syntax highlighting, you will need to add custom CSS to your +theme. You can generate this CSS using the `pygmentize` command as follows: + + mkdir -p files/assets/css + pygmentize -S <PYGMENTS_STYLE> -a .highlight -f html >> files/assets/css/custom.css + +and make sure that `custom.css` is included in your site by your +theme. The various available style options for `<PYGMENTS_STYLE>` can be found +using the command `pygmentize -L style`. + +## Customization + +You can add any customization variables that you wish to add, to modify the +output generated by org-mode to `conf.el` inside the plugin directory. This +lets you have custom configuration, that doesn't get wiped out each time the +plugin is updated. + +## Teasers + +You may use teasers by enabling `INDEX_TEASERS = True` in conf.py, and +use `{{{TEASER_END}}}` to generate `<!-- TEASER_END -->` in org posts. + +## Image URLs + +The image url in ox-html is a little fuzzy. For example, `[[/images/test.jpg]]` will be +generated as `<img src="file:///images/test.jpg" alt="test.jpg">` +because the path is considered as an absolute file path. + +In order to correctly generate image urls, you may write `[[img-url:/images/test.jpg]]`, +and then it should be generated as `<img src="/images/test.jpg" alt="test.jpg">`. diff --git a/site-src/plugins/orgmode/__pycache__/orgmode.cpython-36.pyc b/site-src/plugins/orgmode/__pycache__/orgmode.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..0b7389b --- /dev/null +++ b/site-src/plugins/orgmode/__pycache__/orgmode.cpython-36.pyc diff --git a/site-src/plugins/orgmode/conf.py.sample b/site-src/plugins/orgmode/conf.py.sample new file mode 100644 index 0000000..e194282 --- /dev/null +++ b/site-src/plugins/orgmode/conf.py.sample @@ -0,0 +1,8 @@ +# NOTE: Needs additional configuration in init.el file. + +# Add the orgmode compiler to your COMPILERS dict. +COMPILERS["orgmode"] = ('.org',) + +# Add org files to your POSTS, PAGES +POSTS = POSTS + (("posts/*.org", "posts", "post.tmpl"),) +PAGES = PAGES + (("stories/*.org", "stories", "story.tmpl"),) diff --git a/site-src/plugins/orgmode/init.el b/site-src/plugins/orgmode/init.el new file mode 100644 index 0000000..0225e45 --- /dev/null +++ b/site-src/plugins/orgmode/init.el @@ -0,0 +1,126 @@ +;; Init file to use with the orgmode plugin. + +;; Load org-mode +;; Requires org-mode v8.x + +(require 'package) +(setq package-load-list '((htmlize t))) +(package-initialize) + +(require 'org) +(require 'ox-html) + +;;; Custom configuration for the export. + +;;; Add any custom configuration that you would like to 'conf.el'. +(setq nikola-use-pygments t + org-export-with-toc nil + org-export-with-section-numbers nil + org-startup-folded 'showeverything) + +;; Load additional configuration from conf.el +(let ((conf (expand-file-name "conf.el" (file-name-directory load-file-name)))) + (if (file-exists-p conf) + (load-file conf))) + +;;; Macros + +;; Load Nikola macros +(setq nikola-macro-templates + (with-current-buffer + (find-file + (expand-file-name "macros.org" (file-name-directory load-file-name))) + (org-macro--collect-macros))) + +;;; Code highlighting +(defun org-html-decode-plain-text (text) + "Convert HTML character to plain TEXT. i.e. do the inversion of + `org-html-encode-plain-text`. Possible conversions are set in + `org-html-protect-char-alist'." + (mapc + (lambda (pair) + (setq text (replace-regexp-in-string (cdr pair) (car pair) text t t))) + (reverse org-html-protect-char-alist)) + text) + +;; Use pygments highlighting for code +(defun pygmentize (lang code) + "Use Pygments to highlight the given code and return the output" + (with-temp-buffer + (insert code) + (let ((lang (or (cdr (assoc lang org-pygments-language-alist)) "text"))) + (shell-command-on-region (point-min) (point-max) + (format "pygmentize -f html -l %s" lang) + (buffer-name) t)) + (buffer-string))) + +(defconst org-pygments-language-alist + '(("asymptote" . "asymptote") + ("awk" . "awk") + ("c" . "c") + ("c++" . "cpp") + ("cpp" . "cpp") + ("clojure" . "clojure") + ("css" . "css") + ("d" . "d") + ("emacs-lisp" . "scheme") + ("F90" . "fortran") + ("gnuplot" . "gnuplot") + ("groovy" . "groovy") + ("haskell" . "haskell") + ("java" . "java") + ("js" . "js") + ("julia" . "julia") + ("latex" . "latex") + ("lisp" . "lisp") + ("makefile" . "makefile") + ("matlab" . "matlab") + ("mscgen" . "mscgen") + ("ocaml" . "ocaml") + ("octave" . "octave") + ("perl" . "perl") + ("picolisp" . "scheme") + ("python" . "python") + ("r" . "r") + ("ruby" . "ruby") + ("sass" . "sass") + ("scala" . "scala") + ("scheme" . "scheme") + ("sh" . "sh") + ("sql" . "sql") + ("sqlite" . "sqlite3") + ("tcl" . "tcl")) + "Alist between org-babel languages and Pygments lexers. +lang is downcased before assoc, so use lowercase to describe language available. +See: http://orgmode.org/worg/org-contrib/babel/languages.html and +http://pygments.org/docs/lexers/ for adding new languages to the mapping.") + +;; Override the html export function to use pygments +(defun org-html-src-block (src-block contents info) + "Transcode a SRC-BLOCK element from Org to HTML. +CONTENTS holds the contents of the item. INFO is a plist holding +contextual information." + (if (org-export-read-attribute :attr_html src-block :textarea) + (org-html--textarea-block src-block) + (let ((lang (org-element-property :language src-block)) + (code (org-element-property :value src-block)) + (code-html (org-html-format-code src-block info))) + (if nikola-use-pygments + (pygmentize (downcase lang) (org-html-decode-plain-text code)) + code-html)))) + +;; Export images with custom link type +(defun org-custom-link-img-url-export (path desc format) + (cond + ((eq format 'html) + (format "<img src=\"%s\" alt=\"%s\"/>" path desc)))) +(org-add-link-type "img-url" nil 'org-custom-link-img-url-export) + +;; Export function used by Nikola. +(defun nikola-html-export (infile outfile) + "Export the body only of the input file and write it to +specified location." + (with-current-buffer (find-file infile) + (org-macro-replace-all nikola-macro-templates) + (org-html-export-as-html nil nil t t) + (write-file outfile nil))) diff --git a/site-src/plugins/orgmode/macros.org b/site-src/plugins/orgmode/macros.org new file mode 100644 index 0000000..c90be7f --- /dev/null +++ b/site-src/plugins/orgmode/macros.org @@ -0,0 +1,19 @@ +# Macros for embedding media into org-mode posts. + +#+MACRO: TEASER_END #+HTML: <!-- TEASER_END --> +{{{TEASER_END}}} + +#+MACRO: gist #+HTML: <script src="https://gist.github.com/$1.js"></script> +{{{gist(2395294)}}} + +#+MACRO: soundcloud #+HTML: <iframe width="$3" height="$2" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/$1"> </iframe> +{{{soundcloud(31824842,240,320)}}} + +#+MACRO: soundcloud_playlist #+HTML: <iframe width="$3" height="$2" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https://api.soundcloud.com/playlists/$1"> </iframe> +{{{soundcloud_playlist(694081,800,400)}}} + +#+MACRO: vimeo #+HTML: <iframe src="https://player.vimeo.com/video/$1" width="$3" height="$2" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen> </iframe> +{{{vimeo(85360039,240,320)}}} + +#+MACRO: youtube #+HTML: <iframe width="$3" height="$2" src="https://www.youtube.com/embed/$1?rel=0&hd=1&wmode=transparent"></iframe> +{{{youtube(8N_tupPBtWQ,240,320)}}} diff --git a/site-src/plugins/orgmode/orgmode.plugin b/site-src/plugins/orgmode/orgmode.plugin new file mode 100644 index 0000000..8f74cf0 --- /dev/null +++ b/site-src/plugins/orgmode/orgmode.plugin @@ -0,0 +1,15 @@ +[Core] +Name = orgmode +Module = orgmode + + +[Nikola] +MinVersion = 6.0.0 +PluginCategory = Compiler + +[Documentation] +Author = Puneeth Chaganti +Version = 0.3 +Website = http://plugins.getnikola.com/#orgmode +Description = Compile org-mode markup into HTML using emacs. + diff --git a/site-src/plugins/orgmode/orgmode.py b/site-src/plugins/orgmode/orgmode.py new file mode 100644 index 0000000..c2124f6 --- /dev/null +++ b/site-src/plugins/orgmode/orgmode.py @@ -0,0 +1,129 @@ +# -*- 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 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(), with_dependencies=True) + 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})'.format( + source, e.returncode)) + + def compile_html(self, source, dest, is_two_file=True): + """Compile the post into HTML (deprecated API).""" + try: + post = self.site.post_per_input_file[source] + except KeyError: + post = None + + return compile(source, dest, is_two_file, post, None) + + def create_post(self, path, **kw): + content = kw.pop('content', None) + onefile = kw.pop('onefile', False) + kw.pop('is_page', False) + + 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.') diff --git a/site-src/plugins/orgmode/requirements-nonpy.txt b/site-src/plugins/orgmode/requirements-nonpy.txt new file mode 100644 index 0000000..4ccd98d --- /dev/null +++ b/site-src/plugins/orgmode/requirements-nonpy.txt @@ -0,0 +1,2 @@ +Emacs::https://www.gnu.org/software/emacs/ +Org-mode::http://orgmode.org/ |