diff --git a/conf.py b/conf.py index 6ed8f58e..6071aa70 100644 --- a/conf.py +++ b/conf.py @@ -14,6 +14,7 @@ NAVIGATION_LINKS = { DEFAULT_LANG: ( ('/index.html', 'Home'), ('/stories/about.html', 'About me'), + ('/stories/privacy.html', 'Privacy'), #( #( #('http://www.donaldharper.com', 'My Photo Blog'), diff --git a/plugins/rest_html5/README.md b/plugins/rest_html5/README.md new file mode 100644 index 00000000..acd5eb2c --- /dev/null +++ b/plugins/rest_html5/README.md @@ -0,0 +1 @@ +Modified version of original reST plugin that uses an [alternative docutils writer](https://bitbucket.org/andre_felipe_dias/rst2html5) to produce HTML5 output. diff --git a/plugins/rest_html5/requirements.txt b/plugins/rest_html5/requirements.txt new file mode 100644 index 00000000..0821a462 --- /dev/null +++ b/plugins/rest_html5/requirements.txt @@ -0,0 +1 @@ +rst2html5 diff --git a/plugins/rest_html5/rest_html5.plugin b/plugins/rest_html5/rest_html5.plugin new file mode 100644 index 00000000..3812881b --- /dev/null +++ b/plugins/rest_html5/rest_html5.plugin @@ -0,0 +1,13 @@ +[Core] +Name = rest_html5 +Module = rest_html5 + +[Nikola] +Compiler = rest + +[Documentation] +Author = Roberto Alsina, Pelle Nilsson +Version = 1.0 +Website = http://plugins.getnikola.com/#rest_html5 +Description = Compile reST into HTML5 + diff --git a/plugins/rest_html5/rest_html5.py b/plugins/rest_html5/rest_html5.py new file mode 100644 index 00000000..576b1dd7 --- /dev/null +++ b/plugins/rest_html5/rest_html5.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- + +# Copyright © 2012-2015 Roberto Alsina 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. + +from __future__ import unicode_literals +import io +import os +import re + +try: + import docutils.core + import docutils.nodes + import docutils.utils + import docutils.io + import docutils.readers.standalone + has_docutils = True +except ImportError: + has_docutils = False + +try: + import rst2html5 + has_rst2html5 = True +except ImportError: + has_rst2html5 = False + +from nikola.plugin_categories import PageCompiler +from nikola.utils import get_logger, makedirs, req_missing, write_metadata + + +class CompileRestHTML5(PageCompiler): + """Compile reSt into HTML.""" + + name = "rest_html5" + demote_headers = True + logger = None + + def _read_extra_deps(self, post): + """Reads contents of .dep file and returns them as a list""" + dep_path = post.base_path + '.dep' + if os.path.isfile(dep_path): + with io.open(dep_path, 'r+', encoding='utf8') as depf: + deps = [l.strip() for l in depf.readlines()] + return deps + return [] + + def register_extra_dependencies(self, post): + """Adds dependency to post object to check .dep file.""" + post.add_dependency(lambda: self._read_extra_deps(post), 'fragment') + + def compile_html(self, source, dest, is_two_file=True): + """Compile reSt into HTML.""" + + if not has_docutils: + req_missing(['docutils'], 'build this site (compile reStructuredText)') + if not has_rst2html5: + req_missing(['rst2html5'], 'build this site (compile reStructuredText into HTML5)') + makedirs(os.path.dirname(dest)) + error_level = 100 + with io.open(dest, "w+", encoding="utf8") as out_file: + with io.open(source, "r", encoding="utf8") as in_file: + data = in_file.read() + add_ln = 0 + if not is_two_file: + spl = re.split('(\n\n|\r\n\r\n)', data, maxsplit=1) + data = spl[-1] + if len(spl) != 1: + # If errors occur, this will be added to the line + # number reported by docutils so the line number + # matches the actual line number (off by 7 with default + # metadata, could be more or less depending on the post + # author). + add_ln = len(spl[0].splitlines()) + 1 + + default_template_path = os.path.join(os.path.dirname(__file__), 'template.txt') + output, error_level, deps = rst2html( + data, settings_overrides={ + 'initial_header_level': 0, + 'record_dependencies': True, + 'stylesheet_path': None, + 'link_stylesheet': True, + 'syntax_highlight': 'short', + 'math_output': 'mathjax', + 'template': default_template_path, + }, logger=self.logger, source_path=source, l_add_ln=add_ln) + out_file.write(output) + deps_path = dest + '.dep' + if deps.list: + with io.open(deps_path, "w+", encoding="utf8") as deps_file: + deps_file.write('\n'.join(deps.list)) + else: + if os.path.isfile(deps_path): + os.unlink(deps_path) + if error_level < 3: + return True + else: + return False + + def create_post(self, path, **kw): + content = kw.pop('content', None) + onefile = kw.pop('onefile', False) + # is_page is not used by create_post as of now. + kw.pop('is_page', False) + metadata = {} + metadata.update(self.default_metadata) + metadata.update(kw) + makedirs(os.path.dirname(path)) + if not content.endswith('\n'): + content += '\n' + with io.open(path, "w+", encoding="utf8") as fd: + if onefile: + fd.write(write_metadata(metadata)) + fd.write('\n') + fd.write(content) + + def set_site(self, site): + self.config_dependencies = [] + for plugin_info in site.plugin_manager.getPluginsOfCategory("RestExtension"): + if plugin_info.name in site.config['DISABLED_PLUGINS']: + site.plugin_manager.removePluginFromCategory(plugin_info, "RestExtension") + continue + + site.plugin_manager.activatePluginByName(plugin_info.name) + self.config_dependencies.append(plugin_info.name) + plugin_info.plugin_object.set_site(site) + plugin_info.plugin_object.short_help = plugin_info.description + + self.logger = get_logger('compile_rest', site.loghandlers) + if not site.debug: + self.logger.level = 4 + + return super(CompileRestHTML5, self).set_site(site) + + +def get_observer(settings): + """Return an observer for the docutils Reporter.""" + def observer(msg): + """Report docutils/rest messages to a Nikola user. + + Error code mapping: + + +------+---------+------+----------+ + | dNUM | dNAME | lNUM | lNAME | d = docutils, l = logbook + +------+---------+------+----------+ + | 0 | DEBUG | 1 | DEBUG | + | 1 | INFO | 2 | INFO | + | 2 | WARNING | 4 | WARNING | + | 3 | ERROR | 5 | ERROR | + | 4 | SEVERE | 6 | CRITICAL | + +------+---------+------+----------+ + """ + errormap = {0: 1, 1: 2, 2: 4, 3: 5, 4: 6} + text = docutils.nodes.Element.astext(msg) + line = msg['line'] + settings['add_ln'] if 'line' in msg else 0 + out = '[{source}{colon}{line}] {text}'.format( + source=settings['source'], colon=(':' if line else ''), + line=line, text=text) + settings['logger'].log(errormap[msg['level']], out) + + return observer + + +class NikolaReader(docutils.readers.standalone.Reader): + + def new_document(self): + """Create and return a new empty document tree (root node).""" + document = docutils.utils.new_document(self.source.source_path, self.settings) + document.reporter.stream = False + document.reporter.attach_observer(get_observer(self.l_settings)) + return document + + +def add_node(node, visit_function=None, depart_function=None): + """ + Register a Docutils node class. + This function is completely optional. It is a same concept as + `Sphinx add_node function `_. + + For example:: + + class Plugin(RestExtension): + + name = "rest_math" + + def set_site(self, site): + self.site = site + directives.register_directive('math', MathDirective) + add_node(MathBlock, visit_Math, depart_Math) + return super(Plugin, self).set_site(site) + + class MathDirective(Directive): + def run(self): + node = MathBlock() + return [node] + + class Math(docutils.nodes.Element): pass + + def visit_Math(self, node): + self.body.append(self.starttag(node, 'math')) + + def depart_Math(self, node): + self.body.append('') + + For full example, you can refer to `Microdata plugin `_ + """ + docutils.nodes._add_node_class_names([node.__name__]) + if visit_function: + setattr(rst2html5.HTML5Translator, 'visit_' + node.__name__, visit_function) + if depart_function: + setattr(rst2html5.HTML5Translator, 'depart_' + node.__name__, depart_function) + + +def rst2html(source, source_path=None, source_class=docutils.io.StringInput, + destination_path=None, reader=None, + parser=None, parser_name='restructuredtext', writer=None, + writer_name='html5', settings=None, settings_spec=None, + settings_overrides=None, config_section=None, + enable_exit_status=None, logger=None, l_add_ln=0): + """ + Set up & run a `Publisher`, and return a dictionary of document parts. + Dictionary keys are the names of parts, and values are Unicode strings; + encoding is up to the client. For programmatic use with string I/O. + + For encoded string input, be sure to set the 'input_encoding' setting to + the desired encoding. Set it to 'unicode' for unencoded Unicode string + input. Here's how:: + + publish_parts(..., settings_overrides={'input_encoding': 'unicode'}) + + Parameters: see `publish_programmatically`. + + WARNING: `reader` should be None (or NikolaReader()) if you want Nikola to report + reStructuredText syntax errors. + """ + if reader is None: + reader = NikolaReader() + # For our custom logging, we have special needs and special settings we + # specify here. + # logger a logger from Nikola + # source source filename (docutils gets a string) + # add_ln amount of metadata lines (see comment in compile_html above) + reader.l_settings = {'logger': logger, 'source': source_path, + 'add_ln': l_add_ln} + + if writer is None: + writer = rst2html5.HTML5Writer() + + pub = docutils.core.Publisher(reader, parser, writer, settings=settings, + source_class=source_class, + destination_class=docutils.io.StringOutput) + pub.set_components(None, parser_name, writer_name) + pub.process_programmatic_settings( + settings_spec, settings_overrides, config_section) + pub.set_source(source, None) + pub.settings._nikola_source_path = source_path + pub.set_destination(None, destination_path) + pub.publish(enable_exit_status=enable_exit_status) + + return pub.writer.parts['body'], pub.document.reporter.max_level, pub.settings.record_dependencies diff --git a/posts/2015/07/gallery-test.rst b/posts/2015/07/gallery-test.rst new file mode 100644 index 00000000..3e59b56d --- /dev/null +++ b/posts/2015/07/gallery-test.rst @@ -0,0 +1,20 @@ +.. title: Gallery Test +.. slug: gallery-test +.. date: 2115-07-14 21:02:09 UTC-05:00 +.. tags: photos +.. category: +.. link: +.. description: +.. type: text + + +This is a test of the gallery plugin: + +.. gallery:: demo + +and we should have a nice gallery. Cool, eh? + +Click on a photo to see it bigger, then click on the right side to move forward in the list. + +Neat! + diff --git a/posts/exit-stage-left.rst b/posts/exit-stage-left.rst new file mode 100644 index 00000000..3b530019 --- /dev/null +++ b/posts/exit-stage-left.rst @@ -0,0 +1,17 @@ +.. title: Exit, Stage Left +.. slug: exit-stage-left +.. date: 2025-11-29 19:11:43 UTC-06:00 +.. tags: personal,work +.. category: +.. link: +.. description: +.. type: text + + +So, the current gig is not what I expected when I interviewed. While the people working there are dedicated, intelligent, and hard-working, the fit is not right for me. I’m going to rhetorically vote with my feet and go elsewhere — in the words of the immortal and beloved Snagglepuss, “Exit, stage left.” + +Starting XXXX, I will be transitioning into a new roll doing something. + +This is a future post, just to capture that quote. ;) + +d diff --git a/stories/privacy.rst b/stories/privacy.rst new file mode 100644 index 00000000..282a1f92 --- /dev/null +++ b/stories/privacy.rst @@ -0,0 +1,12 @@ +.. title: Privacy +.. slug: privacy +.. date: 2015-12-20 10:15:22 UTC-06:00 +.. tags: +.. category: +.. link: +.. description: +.. type: text + +As someone who is supports computers for a living, privacy and security are thing for me. The logging on this site is only for debugging issues, and is not stored for more than 4 weeks at the moment (this will probably be shortened soon). There should be no cookies set by this site. When we switch over to only SSL/TLS traffic, the server will be configured to only serve TLS traffic. + +I **may** put a local traffic analyser on to look at things, but until this site gets popular enough, it will not matter.