forked from oddbird/susysite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
07ddb36
commit 78550e8
Showing
27 changed files
with
619 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "output"] | ||
path = output | ||
url = [email protected]:ericam/susy.oddbird.net.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
source "http://rubygems.org" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
clean: | ||
find content -name *~ -delete | ||
rm -rf output/* | ||
|
||
build: clean | ||
python run.py build content/ | ||
|
||
serve: build | ||
python run.py serve content/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Compass CSS framework config file | ||
|
||
project_type = :stand_alone | ||
# Set this to the root of your project when deployed: | ||
http_path = "/" | ||
sass_dir = "sass" | ||
css_dir = "content/static/css" | ||
images_dir = "content/static/images" | ||
fonts_dir = "content/static/fonts" | ||
javascripts_dir = "content/static/js" | ||
line_comments = false | ||
preferred_syntax = :scss | ||
output_style = :expanded | ||
relative_assets = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
public: yes | ||
|
||
|
||
Page not found. | ||
=============== | ||
|
||
That's odd. | ||
You can always return home_ | ||
and explore our site from there. | ||
|
||
.. _home: / |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
susy.oddbird.net | ||
================ | ||
|
||
New home for the Susy website |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--- | ||
active_modules: [pygments, tags, blog, typogrify] | ||
author: Eric A. Meyer | ||
canonical_url: http://susy.oddbird.com/ | ||
output_folder: ../output | ||
template_path: ../templates | ||
modules: | ||
pygments: | ||
style: borland | ||
blog: | ||
index_url: /blog/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
public: yes | ||
hide_title: yes | ||
|
||
|
||
Home | ||
==== | ||
|
||
Hello World! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
User-agent: * | ||
Disallow: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,245 @@ | ||
import re | ||
import smartypants | ||
|
||
|
||
def amp(text): | ||
"""Wraps apersands in HTML with ``<span class="amp">`` so they can be | ||
styled with CSS. Apersands are also normalized to ``&``. Requires | ||
ampersands to have whitespace or an `` `` on both sides. | ||
>>> amp('One & two') | ||
u'One <span class="amp">&</span> two' | ||
>>> amp('One & two') | ||
u'One <span class="amp">&</span> two' | ||
>>> amp('One & two') | ||
u'One <span class="amp">&</span> two' | ||
>>> amp('One & two') | ||
u'One <span class="amp">&</span> two' | ||
It won't mess up & that are already wrapped, in entities or URLs | ||
>>> amp('One <span class="amp">&</span> two') | ||
u'One <span class="amp">&</span> two' | ||
>>> amp('“this” & <a href="/?that&test">that</a>') | ||
u'“this” <span class="amp">&</span> <a href="/?that&test">that</a>' | ||
It should ignore standalone amps that are in attributes | ||
>>> amp('<link href="xyz.html" title="One & Two">xyz</link>') | ||
u'<link href="xyz.html" title="One & Two">xyz</link>' | ||
""" | ||
text = unicode(text) | ||
# tag_pattern from http://haacked.com/archive/2004/10/25/usingregularexpressionstomatchhtml.aspx | ||
# it kinda sucks but it fixes the standalone amps in attributes bug | ||
tag_pattern = '</?\w+((\s+\w+(\s*=\s*(?:".*?"|\'.*?\'|[^\'">\s]+))?)+\s*|\s*)/?>' | ||
amp_finder = re.compile(r"(\s| )(&|&|&\#38;)(\s| )") | ||
intra_tag_finder = re.compile(r'(?P<prefix>(%s)?)(?P<text>([^<]*))(?P<suffix>(%s)?)' % (tag_pattern, tag_pattern)) | ||
def _amp_process(groups): | ||
prefix = groups.group('prefix') or '' | ||
text = amp_finder.sub(r"""\1<span class="amp">&</span>\3""", groups.group('text')) | ||
suffix = groups.group('suffix') or '' | ||
return prefix + text + suffix | ||
output = intra_tag_finder.sub(_amp_process, text) | ||
return output | ||
|
||
|
||
def caps(text): | ||
"""Wraps multiple capital letters in ``<span class="caps">`` | ||
so they can be styled with CSS. | ||
>>> caps("A message from KU") | ||
u'A message from <span class="caps">KU</span>' | ||
Uses the smartypants tokenizer to not screw with HTML or with tags it shouldn't. | ||
>>> caps("<PRE>CAPS</pre> more CAPS") | ||
u'<PRE>CAPS</pre> more <span class="caps">CAPS</span>' | ||
>>> caps("A message from 2KU2 with digits") | ||
u'A message from <span class="caps">2KU2</span> with digits' | ||
>>> caps("Dotted caps followed by spaces should never include them in the wrap D.O.T. like so.") | ||
u'Dotted caps followed by spaces should never include them in the wrap <span class="caps">D.O.T.</span> like so.' | ||
All caps with with apostrophes in them shouldn't break. Only handles dump apostrophes though. | ||
>>> caps("JIMMY'S") | ||
u'<span class="caps">JIMMY\\'S</span>' | ||
>>> caps("<i>D.O.T.</i>HE34T<b>RFID</b>") | ||
u'<i><span class="caps">D.O.T.</span></i><span class="caps">HE34T</span><b><span class="caps">RFID</span></b>' | ||
""" | ||
text = unicode(text) | ||
|
||
tokens = smartypants._tokenize(text) | ||
result = [] | ||
in_skipped_tag = False | ||
|
||
cap_finder = re.compile(r"""( | ||
(\b[A-Z\d]* # Group 2: Any amount of caps and digits | ||
[A-Z]\d*[A-Z] # A cap string much at least include two caps (but they can have digits between them) | ||
[A-Z\d']*\b) # Any amount of caps and digits or dumb apostsrophes | ||
| (\b[A-Z]+\.\s? # OR: Group 3: Some caps, followed by a '.' and an optional space | ||
(?:[A-Z]+\.\s?)+) # Followed by the same thing at least once more | ||
(?:\s|\b|$)) | ||
""", re.VERBOSE) | ||
|
||
def _cap_wrapper(matchobj): | ||
"""This is necessary to keep dotted cap strings to pick up extra spaces""" | ||
if matchobj.group(2): | ||
return """<span class="caps">%s</span>""" % matchobj.group(2) | ||
else: | ||
if matchobj.group(3)[-1] == " ": | ||
caps = matchobj.group(3)[:-1] | ||
tail = ' ' | ||
else: | ||
caps = matchobj.group(3) | ||
tail = '' | ||
return """<span class="caps">%s</span>%s""" % (caps, tail) | ||
|
||
tags_to_skip_regex = re.compile("<(/)?(?:pre|code|kbd|script|math)[^>]*>", re.IGNORECASE) | ||
|
||
|
||
for token in tokens: | ||
if token[0] == "tag": | ||
# Don't mess with tags. | ||
result.append(token[1]) | ||
close_match = tags_to_skip_regex.match(token[1]) | ||
if close_match and close_match.group(1) == None: | ||
in_skipped_tag = True | ||
else: | ||
in_skipped_tag = False | ||
else: | ||
if in_skipped_tag: | ||
result.append(token[1]) | ||
else: | ||
result.append(cap_finder.sub(_cap_wrapper, token[1])) | ||
output = "".join(result) | ||
return output | ||
|
||
|
||
def initial_quotes(text): | ||
"""Wraps initial quotes in ``class="dquo"`` for double quotes or | ||
``class="quo"`` for single quotes. Works in these block tags ``(h1-h6, p, li, dt, dd)`` | ||
and also accounts for potential opening inline elements ``a, em, strong, span, b, i`` | ||
>>> initial_quotes('"With primes"') | ||
u'<span class="dquo">"</span>With primes"' | ||
>>> initial_quotes("'With single primes'") | ||
u'<span class="quo">\\'</span>With single primes\\'' | ||
>>> initial_quotes('<a href="#">"With primes and a link"</a>') | ||
u'<a href="#"><span class="dquo">"</span>With primes and a link"</a>' | ||
>>> initial_quotes('“With smartypanted quotes”') | ||
u'<span class="dquo">“</span>With smartypanted quotes”' | ||
""" | ||
text = unicode(text) | ||
quote_finder = re.compile(r"""((<(p|h[1-6]|li|dt|dd)[^>]*>|^) # start with an opening p, h1-6, li, dd, dt or the start of the string | ||
\s* # optional white space! | ||
(<(a|em|span|strong|i|b)[^>]*>\s*)*) # optional opening inline tags, with more optional white space for each. | ||
(("|“|&\#8220;)|('|‘|&\#8216;)) # Find me a quote! (only need to find the left quotes and the primes) | ||
# double quotes are in group 7, singles in group 8 | ||
""", re.VERBOSE) | ||
def _quote_wrapper(matchobj): | ||
if matchobj.group(7): | ||
classname = "dquo" | ||
quote = matchobj.group(7) | ||
else: | ||
classname = "quo" | ||
quote = matchobj.group(8) | ||
return """%s<span class="%s">%s</span>""" % (matchobj.group(1), classname, quote) | ||
output = quote_finder.sub(_quote_wrapper, text) | ||
return output | ||
|
||
|
||
def smartquotes(text): | ||
"""Applies smarty pants to curl quotes. | ||
>>> smartquotes('The "Green" man') | ||
u'The “Green” man' | ||
""" | ||
text = unicode(text) | ||
output = smartypants.smartyPants(text) | ||
return output | ||
|
||
|
||
def typogrify(text): | ||
"""The super typography filter | ||
Applies the following filters: widont, smartquotes, caps, amp, initial_quotes | ||
>>> typogrify('<h2>"Jayhawks" & KU fans act extremely obnoxiously</h2>') | ||
u'<h2><span class="dquo">“</span>Jayhawks” <span class="amp">&</span> <span class="caps">KU</span> fans act extremely obnoxiously</h2>' | ||
""" | ||
text = unicode(text) | ||
text = amp(text) | ||
text = widont(text) | ||
text = smartquotes(text) | ||
text = caps(text) | ||
text = initial_quotes(text) | ||
return text | ||
|
||
|
||
def widont(text): | ||
"""Replaces the space between the last two words in a string with `` `` | ||
Works in these block tags ``(h1-h6, p, li, dd, dt)`` and also accounts for | ||
potential closing inline elements ``a, em, strong, span, b, i`` | ||
>>> widont('A very simple test') | ||
u'A very simple test' | ||
Single word items shouldn't be changed | ||
>>> widont('Test') | ||
u'Test' | ||
>>> widont(' Test') | ||
u' Test' | ||
>>> widont('<ul><li>Test</p></li><ul>') | ||
u'<ul><li>Test</p></li><ul>' | ||
>>> widont('<ul><li> Test</p></li><ul>') | ||
u'<ul><li> Test</p></li><ul>' | ||
>>> widont('<p>In a couple of paragraphs</p><p>paragraph two</p>') | ||
u'<p>In a couple of paragraphs</p><p>paragraph two</p>' | ||
>>> widont('<h1><a href="#">In a link inside a heading</i> </a></h1>') | ||
u'<h1><a href="#">In a link inside a heading</i> </a></h1>' | ||
>>> widont('<p>Some text <a href="#">nearly ends with a link</a>.</p>') | ||
u'<p>Some text <a href="#">nearly ends with a link</a>.</p>' | ||
>>> widont('<h1><a href="#">In a link</a> followed by other text</h1>') | ||
u'<h1><a href="#">In a link</a> followed by other text</h1>' | ||
Empty HTMLs shouldn't error | ||
>>> widont('<h1><a href="#"></a></h1>') | ||
u'<h1><a href="#"></a></h1>' | ||
>>> widont('<div>Divs get no love!</div>') | ||
u'<div>Divs get no love!</div>' | ||
>>> widont('<pre>Neither do PREs</pre>') | ||
u'<pre>Neither do PREs</pre>' | ||
>>> widont('<div><p>But divs with paragraphs do!</p></div>') | ||
u'<div><p>But divs with paragraphs do!</p></div>' | ||
""" | ||
text = unicode(text) | ||
widont_finder = re.compile(r"""((?:</?(?:a|em|span|strong|i|b)[^>]*>)|[^<>\s]) # must be proceeded by an approved inline opening or closing tag or a nontag/nonspace | ||
\s+ # the space to replace | ||
([^<>\s]+ # must be followed by non-tag non-space characters | ||
\s* # optional white space! | ||
(</(a|em|span|strong|i|b)>\s*)* # optional closing inline tags with optional white space after each | ||
\.? # optional period | ||
((</(p|h[1-6]|li|dt|dd)>)|$)) # end with a closing p, h1-6, li or the end of the string | ||
""", re.VERBOSE) | ||
output = widont_finder.sub(r'\1 \2', text) | ||
return output | ||
|
||
|
||
def _test(): | ||
import doctest | ||
doctest.testmod() | ||
|
||
if __name__ == "__main__": | ||
_test() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from __future__ import absolute_import | ||
|
||
from jinja2 import Markup | ||
from rstblog.programs import RSTProgram | ||
|
||
import typogrify | ||
|
||
|
||
class TypogrifyRSTProgram(RSTProgram): | ||
def get_fragments(self): | ||
if self._fragment_cache is not None: | ||
return self._fragment_cache | ||
with self.context.open_source_file() as f: | ||
self.get_header(f) | ||
rv = self.context.render_rst(f.read().decode('utf-8')) | ||
rv['fragment'] = Markup(typogrify.typogrify(rv['fragment'])) | ||
self._fragment_cache = rv | ||
return rv | ||
|
||
|
||
def setup(builder): | ||
builder.programs['rst'] = TypogrifyRSTProgram |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--extra-index-url http://chishop.oddbird.net/simple | ||
|
||
rstblog==1.0.obc2 | ||
PyYAML==3.10 | ||
Babel==0.9.6 | ||
blinker==1.2 | ||
docutils==0.9.1 | ||
Jinja2==2.6 | ||
Werkzeug==0.8.3 | ||
Pygments==1.5 | ||
smartypants==1.6.0.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/usr/bin/env python | ||
""" | ||
Alternative run-rstblog wrapper script; adds our modules path. | ||
""" | ||
import os, sys | ||
|
||
from rstblog.cli import main | ||
from rstblog.modules import add_module_path | ||
|
||
HERE = os.path.dirname(os.path.abspath(__file__)) | ||
MODULES = os.path.join(HERE, "modules") | ||
LIB = os.path.join(HERE, "lib") | ||
|
||
if __name__ == "__main__": | ||
sys.path.insert(0, LIB) | ||
add_module_path(MODULES) | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// Screen | ||
// ====== | ||
|
Oops, something went wrong.