diff --git a/.gitignore b/.gitignore index c553819..97fc977 100644 --- a/.gitignore +++ b/.gitignore @@ -1,37 +1,223 @@ + +# Created by https://www.gitignore.io/api/linux,vim,emacs,python,python +# Edit at https://www.gitignore.io/?templates=linux,vim,emacs,python,python + +### Emacs ### +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + + +### Linux ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ *.py[cod] -pyvenv.cfg -__pycache__ -*.*~ +*$py.class # C extensions *.so -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs +# Distribution / packaging +.Python +build/ +develop-eggs/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ .installed.cfg -lib -lib64 +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec # Installer logs pip-log.txt +pip-delete-this-directory.txt # Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ .coverage -.tox +.coverage.* +.cache nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ # Translations *.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +# End of https://www.gitignore.io/api/linux,vim,emacs,python,python + +# Generated using ignr.py - github.com/Antrikshy/ignr.py +#------------------------------------------------------------------------------ +# Custom +#------------------------------------------------------------------------------ # Mr Developer .mr.developer.cfg .project diff --git a/hovercraft/__init__.py b/hovercraft/__init__.py index 7cf371a..019fe5d 100644 --- a/hovercraft/__init__.py +++ b/hovercraft/__init__.py @@ -5,6 +5,7 @@ import threading import time import pkg_resources +import hovercraft.directive.null from collections import defaultdict from http.server import HTTPServer, SimpleHTTPRequestHandler from tempfile import TemporaryDirectory @@ -155,18 +156,40 @@ def my_gettext(s): #help=('Display version and exit.'), version="Hovercraft! %s" % __version__ ) + parser.add_argument( + '-D', + '--directive-plugin', + action='append', + help=('Package name of the direcvtive plugin to load. ' + 'Can be applied multiple times.'), + ) return parser -def serve_presentation(args): +def register_directive_plugin(plugin, args): + if isinstance(plugin, (str,)): + plugin = __import__(plugin, globals(), locals(), 'module') + print('Registering directive plugin {}.'.format(plugin.__name__)) + plugin.register(args) + +def register_directives(args): + directives = [hovercraft.directive.null] + if args.directive_plugin: + directives.extend(args.directive_plugin) + for plugin in directives: + register_directive_plugin(plugin, args) + + +def serve_presentation(args): # XXX Bit of a hack, clean this up, I check for this twice, also in the template. if args.template and args.template not in ('simple', 'default'): args.template = os.path.abspath(args.template) if args.targetdir: # Generate the presentation + register_directives(args) generate(args) else: # Server mode. Start a server that serves a temporary directory. @@ -174,6 +197,7 @@ def serve_presentation(args): with TemporaryDirectory() as targetdir: args.targetdir = targetdir args.presentation = os.path.abspath(args.presentation) + register_directives(args) # Set up watchdog to regenerate presentation if saved. event = threading.Event() diff --git a/hovercraft/directive/__init__.py b/hovercraft/directive/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hovercraft/directive/null.py b/hovercraft/directive/null.py new file mode 100644 index 0000000..ea7f2cc --- /dev/null +++ b/hovercraft/directive/null.py @@ -0,0 +1,14 @@ +# TODO - Remove this file. It is only here to demonstrate how to implement a +# directive plugin. +from docutils import nodes +from docutils.parsers.rst import Directive, directives + + +class Null(Directive): + def run(self): + para = nodes.paragraph(text='Example null directive') + return [para] + + +def register(_): + directives.register_directive('null', Null) diff --git a/hovercraft/generate.py b/hovercraft/generate.py index 1382267..532d4d8 100644 --- a/hovercraft/generate.py +++ b/hovercraft/generate.py @@ -128,6 +128,10 @@ def copy_resource(filename, sourcedir, targetdir): sourcepath = os.path.join(sourcedir, filename) targetpath = os.path.join(targetdir, filename) + if not os.path.exists(sourcepath) and os.path.exists(targetpath): + # Generated image, no source file available + return None # No monitoring needed + if (os.path.exists(targetpath) and os.path.getmtime(sourcepath) <= os.path.getmtime(targetpath)): # File has not changed since last copy, so skip.