Blog Setup - Implementation 2018-07-08
In this post:
- Fixes to the publisher.
- Things about the publisher that I didn't fix.
- What I accomplished with my custom syntax file.
- What I've yet to accomplish.
Okay, I should summarize what I did before the last post.
- I put checks for error conditions all through the blog publisher script.
- I added a __main__.py file next to it, and made a dumb, probably somewhat mis-written script to invoke it from anywhere. (I judged it to be Too Much Effort right now to turn this into a pip-installable package with command-line entry points.)
- I created a click command group to act as the frontend, registered the "draft" and "publish" tasks with it, and invoked the command group from the module runner.
- I copied some code from Stack Overflow to pop up notifications, then wrote a wrapper around that function to pop up failure notifications on error, and another to pop up success notifications when the command succeeds. (This could possibly be done more compactly-ish with decorators, but it doesn't matter right now.)
There were some things that I want to do sometime, but it wasn't a big deal currently:
- All of the different kinds of directory manipulator are still defined in the same file, and therefore shove the associated globals inside the class definition as a form of namespacing.
- Various aspects of the Three Dollar Quill project are still hardcoded. In the long term, I think I want to have some kind of configuration file at the top level of the blog repository, but there's no particular reason to do this right now.
I also started hacking on copies of the syntax files for Python and reStructuredText. (I can't... find the latter in my syntax picker, not from Sublime? Where did the file go?) I made varying amounts of progress on various areas, and some observations:
- One thing I did was strip out Python 2 compatibility syntax; I tend not to write Python 2 on my own time, and I don't want to deal with maintaining it until after the rest of the syntax does what I want it to.
- I managed to get more metadata and some mini-languages into comments.
- In particular, I managed to get some forms of type annotation comment implementated; this wouldn't normally by of interest for the way I develop, but I'm mildly interested in supporting the 2-3 polyglot, and, indeed, older versions of Python 3, so I'll come back to this later and try to improve on this.
- I managed to delegate the syntax handling for docstrings to a reStructuredText handler, which I had to modify slightly to get syntax handling on the first line of the docstring. I feel like I've gone way beyond the documented features to get this to work.
For some reason, I'm testing the syntax file and the highlighting on the blog publisher script. I guess it's just because it's there.
One thing I haven't looked into is assigning expression scopes to the inside of type annotation strings.
The big thing I haven't gotten working, and the whole reason I went down this rabbit hole in the first place, is assigning a scope to every identifier so I can highlight them. One thing I noticed while figuring out what's needed (basically, identifiers can be divided into some that are only legal at the top level in an expression context, and everything else, which is also legal at the top level, but can also appear in the top level at the left-hand side of an assignment statement, as a class or function name, as a named parameter or argument, and as the target of an as keyword.) is that, even though functions are supposed to have a particular scope when they're called, this isn't actually possible to accomplish in all circumstances. In a multi-line expression, you can put a line break before the open parenthesis, and, near as I can tell, the syntax highlighter is powerless to handle this scenario. This doesn't matter in most practical circumstances, and it doesn't matter for what I want to do, but it's kind of bothersome that the recommended scoping behavior seemingly cannot be guaranteed using the scoping engine.
Looking at how this does, I think I'll just try to preserve the existing behavior as much as possible, on the logic that it's good enough for the official syntax, and do the stuff I want on top of it.
That basically consists of:
- Defining scopes for every kind of identifier that can exist in a program, including the language-provided identifiers, and those provided by the standard library.
- In particular, categorize all identifiers by their use of underscores, and attach the punctuation.definition.variable scope to all relevant underscores.
The main obstacle I have is, I feel like I need to better understand the 50+ contexts defined in the syntax file before I can figure out how to pervasively insert my proposed categorization of names. I think I'll take a break for now, and come back to this later.
(One other tweak that just occurred to me is to have the docstring contexts in the reStructuredText syntax delegate inline literals back to Python. Also, I'm not sure that this syntax has scopes for doctests. I think it should. Need to go over the reStructuredText syntax definition and compare it to what this syntax provides.)
Next time, I wrap this project up.