Alex Raichev

Transitfeed Patch

For the GTFS Explorer project i've been working on, i needed to convert GTFS feeds to KML. Google's transitfeed package is designed to do this, but the latest version (1.2.12) has a bug in it which prevents the KML writer from being imported.

Searching the web on the issue, i found Dylan Vassallo's Github repo pybcp47, which helped me create this patch to squash the bug: transitfeed-1.2.13_unofficial.tar.gz.

To test the KML output online, i used this site.

Author: Alex Raichev
Date: 2013-10-20
Tags: software
Permalink, Comment

Blohg to Pelican

Over the past few days i moved this website's backend from Blohg to Pelican, both of which are RST-capable website generators. I did so, because i don't need the dynamic Flask-application capabilities of Blohg and because Pelican is more mature and equally simple to use.

The transition was mostly smooth, but i did encounter a few issues that required me to search beyond Pelican's documentation to resolve. To save new Pelicaneers the effort, here are those issues and resolutions.

Issue 1: Custom paginated templates.

I wanted a separate landing page and blog page, and the Pelican docs don't elaborate on this point. Querying the Pelican developers through the project's Github page, i received instructions from justinmayer. First, he said, i needed to make a custom template to house my blog, which i called blog.html. It contains the code

{% extends "base.html" %}
{% set active_page = "blog" %}
{% block title %}{{ SITENAME }} - Blog{% endblock %}
{% block content %}
{% for article in (articles_page.object_list if articles_page else articles) %}
    <div class="blogItem">
    <h1><a href="{{ SITEURL }}/{{ article.url }}">{{ article.title }}</a></h1>
    {{ article.content }}

    <div class="blogMeta">
    Author: <a href="mailto: {{ AUTHOR_EMAIL }}">{{ article.author }}</a><br>
    Date: {{ article.locale_date }}<br>
    {% if article.tags %}
        Tags:
        {% for tag in article.tags %}
            <a href="{{ SITEURL }}/{{ tag.url }}">
            {{ tag }}</a>{% if not loop.last %}, {% endif %}
        {% endfor %}<br />
    {% endif %}
    <a href="{{ SITEURL }}/{{ article.url }}#disqus_thread">Comments</a> -
    <a href="{{ SITEURL }}/{{ article.url }}">Permalink</a>
    </div>
    </div><!-- end #blogItem -->
{% endfor %}
{% include 'pagination.html' %}
{% endblock content %}

By the way, here's the code for the pagination template pagination.html:

{% if articles_page and articles_paginator.num_pages > 1 %}
    <div class="pagination">
    <ul>
    {% if articles_page.has_previous() %}
        {% set num = articles_page.previous_page_number() %}
        <li class="prev"><a href="
            {{ SITEURL }}/{{ page_name }}{{ num if num > 1 else ''}}.html"
            >&laquo;</a></li>
    {% endif %}
    {% for num in range( 1, 1 + articles_paginator.num_pages ) %}
        <li><a href="
            {{ SITEURL }}/{{ page_name }}{{ num if num > 1 else '' }}.html"
            class="{{ 'active' if num == articles_page.number else '' }}"
            >{{ num }}</a></li>
    {% endfor %}
    {% if articles_page.has_next() %}
        <li class="next"><a href="
            {{ SITEURL }}/{{ page_name }}{{
               articles_page.next_page_number() }}.html"
            >&raquo;</a></li>
    {% endif %}
    </ul>
    </div>
{% endif %}

I got it from the tuxlit_tbs Pelican theme and modified it to my liking.

Second, i had to add the following lines to my pelicanconf.py.

DIRECT_TEMPLATES = (('index', 'blog', 'tags', 'categories', 'archives'))
PAGINATED_DIRECT_TEMPLATES = (('blog',))

Issue 2: Disqus comments.

This is another topic the Pelican docs don't elaborate on. To embed Disqus comments in my blog pages, i read Disqus's help article on embedding comments and Disqus's help article on adding comment counts and did the following.

First, i made the template disqus_comments.html which contains the code

{% if DISQUS_SITENAME %}
    <div class="blogItem">
    <h2>Comments</h2>
    <div id="disqus_thread"></div>
    <script type="text/javascript">
        var disqus_shortname = '{{ DISQUS_SITENAME }}';
        (function() {
            var dsq = document.createElement('script');
            dsq.type = 'text/javascript';
            dsq.async = true;
            dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] ||
             document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    </script>
    <noscript>
        Please enable JavaScript to view the
        <a href="http://disqus.com/?ref_noscript={{ DISQUS_SITENAME }}">
            comments powered by Disqus.
        </a>
    </noscript>
    <a href="http://disqus.com" class="dsq-brlink">
        blog comments powered by <span class="logo-disqus">Disqus</span>
    </a>
    </div>
{% endif %}

and in my article.html template added the line {% include 'disqus_comments.html' %} before the line {% endblock %}. Doing so embeds Disqus comments for each blog post (article).

Second, i made the template disqus_comment_counts.html which contains the code

{% if DISQUS_SITENAME %}
    <script type="text/javascript">
        var disqus_shortname = '{{ DISQUS_SITENAME }}';
        (function () {
            var s = document.createElement('script'); s.async = true;
            s.type = 'text/javascript';
            s.src = 'http://' + disqus_shortname + '.disqus.com/count.js';
            (document.getElementsByTagName('HEAD')[0] ||
             document.getElementsByTagName('BODY')[0]).appendChild(s);
        }());
    </script>
{% endif %}

and in my base.html template added the line {% include 'disqus_comment_counts.html' %} before the </body> tag. That enables blog post comment counts via the tags <a href="{{ SITEURL }}/{{ article.url }}#disqus_thread">Comments</a>.

Issue 3: Typesetting math.

I wanted to use MathJax to typeset math on this site. Pelican has a LaTeX plugin, which uses MathJax, but doesn't work properly at present. It didn't typeset math in the list view of my blog posts, only in the detail view of each post. So i searched the web for an alternative and found this helpful blog post from another Pelican user. Following its instructions, i added this Javascript code into the <head> section of my base.html template:

<!-- Using MathJax, with the delimiters $ -->
<!-- Conflict with pygments for the .mo and .mi -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
    "HTML-CSS": {
    styles: {
    ".MathJax .mo, .MathJax .mi": {color: "black ! important"}}
    },
    tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']],processEscapes: true}
    });
    MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
    var VARIANT = MathJax.OutputJax["HTML-CSS"].FONTDATA.VARIANT;
    VARIANT["normal"].fonts.unshift("MathJax_SansSerif");
    VARIANT["bold"].fonts.unshift("MathJax_SansSerif-bold");
    VARIANT["italic"].fonts.unshift("MathJax_SansSerif-italic");
    VARIANT["-tex-mathit"].fonts.unshift("MathJax_SansSerif-italic");
    });
    MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
    var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;
    VARIANT["normal"].fonts.unshift("MathJax_SansSerif");
    VARIANT["bold"].fonts.unshift("MathJax_SansSerif-bold");
    VARIANT["italic"].fonts.unshift("MathJax_SansSerif-italic");
    VARIANT["-tex-mathit"].fonts.unshift("MathJax_SansSerif-italic");
    });
</script>

<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML">
</script>

I removed the ['$','$'] item which allows dollar signs to delimit math text, as is standard in LaTeX documents, but it requires escaping every backslash in the math text with an additional backslash. For now i'll stick with the standard RST role :math: for inline math and the standard RST directive .. math:: for block math display. The area of a circle is Ac = (π ⁄ 4)d2, that is,

Ac = (π)/(4)d2.
Author: Alex Raichev
Date: 2013-05-11
Tags: tip, software
Permalink, Comment


Why no comments? I used to do public comments but found that moderating and maintaining them took too much time in front of the computer, time better spent playing outdoors. So these days I only do private comments, that is, you can email me comments regarding a post by clicking the 'Comment' link at the bottom the post.