patternpythonMinor
Markdown parser, template engine, and then some
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:
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
- 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
.jsor.cssfile and links those if appropriate
- Looks for a
page-titlething at the beginning and sets the title to that if it exists
- Puts it all together into a
.htmlfile
- Searches through the
.htmlfile 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
Your
This requires either python 3 or an import:
Unnecessary parens
You don't need the brackets/parens around that conditional, there are only two conditions.
Filename parsing
If you want to parse filenames by yourself rather than using a library, then while your current solution:
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:
String replacement
If you've got a lot of replacements, or you plan on adding more, try an extensible solution instead of all the
logYour
log method can become this:print(a) if DEBUG_MODE else NoneThis requires either python 3 or an import:
from __future__ import print_functionUnnecessary parens
if (ROOT_URL and ROOT_URL != "/")You don't need the brackets/parens around that conditional, there are only two conditions.
rangerange(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 Noneif (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.