Last I left off in part one I generated the content with invoke build. I want to go over the remaining steps on how to preview the content, how I'm publishing it to GitHub pages with the submodule created previously, and also how I plan to use invoke to automate some of this.

Markdown Tweaks

First before previewing the content, I had to make some adjustments to how the Markdown is processed, especially for code blocks. By default pygments, which pelican uses for code highlighting, didn't mesh well with my theme. I made sure to make my pre/code blocks have a dark background for one. I also wanted it to stop guessing the language (it was giving weird results trying to guess at the command line code blocks since they're not really a 'language' per se), and for it to recognize GitHub style fenced blocks (using backticks to surround code blocks instead of relying on indentation).

I added this to my file:

    'extension_configs': {
        'markdown.extensions.codehilite': {'css_class': 'highlight', 'guess_lang': False},
        'markdown.extensions.fenced_code': {},
    'output_format': 'html5',


The invoke build command looks at my file for settings. Some of these settings are theme specific, but they also cover things like what is the site url, how many pages to show before paginating, and so forth. Below I will also be using for prod settings like my Google Analytics tag and FQDN for the site url.

Now that the output directory has my generated content, I want to preview it.

invoke serve

This will create a simple local webserver to show you my content on http://localhost:8000 so I open Firefox and make sure everything seems to be working as expected. I click around, look for formatting weirdness, agonize internally over whether I chose the right theme or not, and then ultimately decide all is well.

That's pretty cool, buuuuuuttttt:


Let's dive a bit more into the invoke command and the default file that is created.

There are lot of built in invoke tasks in this file already like build, serve, and publish. Below are my tweaks.

First I remove the clean, and rebuild commands by commenting them out (maybe I'll redo them in the future). This is becaues they're destructive and will remove the output folder entirely, but remember that I'm using it as a submodule so it is its own git repo. Deleting the whole folder would be too destructive. I also comment out the preview task as I only need to do a prod build when I'm publishing.

Next I need to change how the publish task works because I'm not using rsync to publish this, I'm pushing the content of output to my repo so that it serves automatically with GitHub Pages.

Because I'm running two back to back commands in order to commit the output and the raw content of the main repo, I had to split it into two tasks and have one run before the other. I tried combining this into a single command but it wasn't working. Only one git command would occur and I think that is because the context is lost after git takes control and starts to spit out messages. I'll have to revisit that some day just for curiosity's sake.

def publish_output(c):
    pelican_run('-s {settings_publish}'.format(**CONFIG))

    # Commit the written content to GitHub from this repo
    print(f'In Directory: {os.getcwd()}')'git add .')'git commit -m "auto-commit output from Invoke"')'git push origin master')

def publish(c):
    # Commit the static html pages to repo
    os.chdir('..') # my output folder
    print(f'In Directory: {os.getcwd()}')'git add .')'git commit -m "auto-commit content from Invoke"')'git push origin master')

I only need to run invoke publish and the output directory is refreshed with my new generated site with prod settings from Then the repo gets an auto-commit and push. Followed by thebouv-pelican receiving an auto-commit as well (since the submodule has updated, this step commits updating the submodule to point to the new commit SHA of

But wait, there's more

I noticed in the default file that there is a livereload option. I had to try it out by installing the livereload module and then invoking the task.

pip install livereload
pip freeze > requirements.txt
invoke livereload

Now the browser nicely refreshes for me automatically as I edit and save. That's pretty damn handy.