Browse Source

Add gist directive plugin.

Ionel Cristian Mărieș 9 years ago
parent
commit
84fbe7ca22
3 changed files with 92 additions and 0 deletions
  1. 18 0
      gist_directive/README.rst
  2. 1 0
      gist_directive/__init__.py
  3. 73 0
      gist_directive/gist_directive.py

+ 18 - 0
gist_directive/README.rst

@@ -0,0 +1,18 @@
+Pelican ``gist_directive`` plugin
+=================================
+
+This plugin adds a ``gist`` reStructuredText directive. Eg::
+
+   .. gist:: ionelmc/eb11afbcca187bad5273 setup.py python
+   
+It will download (with cache) and include the gist contents in the document.
+
+.. note::
+
+    It also supports embedding content from github directly.
+    
+    Example, to include ``https://raw.githubusercontent.com/ionelmc/cookiecutter-pylibrary/master/%7B%7Bcookiecutter.repo_name%7D%7D/setup.py``::
+    
+        .. github:: ionelmc/cookiecutter-pylibrary master/{{cookiecutter.repo_name}}/setup.py
+    
+    

+ 1 - 0
gist_directive/__init__.py

@@ -0,0 +1 @@
+from gist_directive import *

+ 73 - 0
gist_directive/gist_directive.py

@@ -0,0 +1,73 @@
+try:
+    from urllib.request import urlopen
+except ImportError:
+    from urllib import urlopen
+import os
+import io
+
+from docutils.parsers.rst import directives
+from pelican.rstdirectives import Pygments
+
+
+def fetch(gid, filename, typ):
+    if not os.path.exists('.gists'):
+        os.mkdir('.gists')
+    key = os.path.join('.gists', ("%s/%s/%s" % (typ, gid, filename)).replace('/', ';'))
+    if os.path.isfile(key):
+        print('LOAD-CACHED:', key)
+        return io.open(key, encoding='utf8').read()
+    else:
+        if typ == 'gist':
+            url = 'https://gist.githubusercontent.com/%s/raw/%s' % (gid, filename)
+        elif typ == 'github':
+            url = 'https://raw.githubusercontent.com/%s/%s' % (gid, filename)
+        else:
+            raise RuntimeError(typ)
+        print('FETCHING:', url)
+        fp = urlopen(url)
+        if fp.getcode() != 200:
+            print('FAILED TO FETCH:', url)
+            print('   status code:', fp.getcode())
+            print('   response:')
+            try:
+                print(fp.read())
+            finally:
+                raise SystemExit()
+        data = fp.read()
+        with open(key, 'wb') as fh:
+            fh.write(data)
+        return data.decode('utf8')
+
+
+class Gist(Pygments):
+    """ Embed Github Gist Snippets in rst text
+
+        GIST_ID and FILENAME are required.
+
+        Usage:
+          .. gist:: GIST_ID FILENAME
+
+    """
+
+    required_arguments = 1
+    optional_arguments = 2
+    has_content = False
+    gist_type = 'gist'
+
+    def run(self):
+        gist = self.arguments[0]
+        filename = self.arguments[1] if len(self.arguments) > 1 else ''
+        language = self.arguments[2] if len(self.arguments) > 2 else None
+        self.arguments = [language]
+
+        self.content = fetch(gist, filename, self.gist_type).splitlines()
+        return super(Gist, self).run()
+
+
+class Github(Gist):
+    gist_type = 'github'
+
+
+def register():
+    directives.register_directive('gist', Gist)
+    directives.register_directive('github', Github)