HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Markdown parser, template engine, and then some

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
enginetemplateparsermarkdownsomethenand

Problem

I've got my own website! Woo! It's got HTML and everything! But after struggling for a while with HTML and keeping my navbar consistent across pages, I gave up and wrote a program which:

  • Searches for every markdown file in the given root directory or below.



  • Parses it into HTML with mistune, which thankfully only needs the one file to work



  • Inserts it into a given template file which contains stuff like a navbar and a footer



  • Looks for a similarly-named .js or .css file and links those if appropriate



  • Looks for a page-title thing at the beginning and sets the title to that if it exists



  • Puts it all together into a .html file



  • Searches through the .html file for any URLs which point to the root of the site and modifies them to point to the real root if, like me, your content is hosted in a subdirectory



  • Writes all that fun stuff to the hard drive for Apache to read



In short, it mashes everything together for a website that actually looks pretty good.

```
# Configuration options:
# =====================

# Where are the files to parse located? (generally ~/www)
# Don't include the trailing slash.
ROOT_PATH = "/home/MY_USERNAME/www"

# Is your site hosted at some prefix? Set ROOT_URL to wherever
# that is and all the URLs which start from root (i.e. start
# with "/") will have it prepended. No trailing slash.
ROOT_URL = "/MY_USERNAME"

# Suppress logging if in fast mode to speed it up some
DEBUG_MODE = False

# ================ #
# Code starts here #
# Do not modify it #
# ================ #

# Imports not at the top because that way it's JUST configuration
# stuff up there.
from glob import glob
import mistune, os, re, sys, time

def log(a):
if DEBUG_MODE:
print(a)

def root_sub(m):
url = m.group(0)
if url.startswith(ROOT_URL):
print(" Found URL starting with site root! Change it!")
return url
if url.startswith("/"):
log(" Prepending site root to URL")
return ROOT_URL + url

Solution

One-lining log

Your log method can become this:

print(a) if DEBUG_MODE else None


This requires either python 3 or an import: from __future__ import print_function

Unnecessary parens

if (ROOT_URL and ROOT_URL != "/")


You don't need the brackets/parens around that conditional, there are only two conditions.

range

range(0, len(files)) can just be range(len(files)), because range starts at 0 by default. The syntax is essentially range(start=0, stop, step=1) - the only mandatory param is stop.

Filename parsing

If you want to parse filenames by yourself rather than using a library, then while your current solution:

path_base = path[0:-3]


is technically safe, and is fine for your current script, but if you want to adapt it for another script, it'll break. A more general, equivalent one-liner is:

path_base = ".".join(path.split('.')[0:-1])


String replacement

If you've got a lot of replacements, or you plan on adding more, try an extensible solution instead of all the replace calls:

replacements = {
    'version': version,
    'style-tag': style_tag,
    'script_tag': script_tag,
    'title-tag': title_tag,
    'markdown': parsed
}
templated = template
for repl_name, repl_val in replacements.iteritems():
    templated.replace('[[{}]]'.format(repl_name), repl_value)

Code Snippets

print(a) if DEBUG_MODE else None
if (ROOT_URL and ROOT_URL != "/")
path_base = path[0:-3]
path_base = ".".join(path.split('.')[0:-1])
replacements = {
    'version': version,
    'style-tag': style_tag,
    'script_tag': script_tag,
    'title-tag': title_tag,
    'markdown': parsed
}
templated = template
for repl_name, repl_val in replacements.iteritems():
    templated.replace('[[{}]]'.format(repl_name), repl_value)

Context

StackExchange Code Review Q#143372, answer score: 2

Revisions (0)

No revisions yet.