Permalink
Browse files

Initial commit.

  • Loading branch information...
sjl committed Jan 24, 2012
1 parent 704056d commit dcdca5d1d362abb870f057708e52fc1148f80c1a
Showing with 1,109 additions and 0 deletions.
  1. +20 −0 LICENSE.markdown
  2. +4 −0 README.markdown
  3. +13 −0 bin/d
  4. 0 d/__init__.py
  5. +197 −0 d/base.py
  6. +356 −0 d/bootstrap.css
  7. +9 −0 d/less.js
  8. +80 −0 d/style.less
  9. +71 −0 d/tango.css
  10. +14 −0 docs/01-installation.markdown
  11. +135 −0 docs/02-usage.markdown
  12. +36 −0 docs/03-customization.markdown
  13. +129 −0 docs/04-faqs.markdown
  14. +1 −0 docs/base
  15. +15 −0 docs/footer.markdown
  16. +18 −0 docs/index.markdown
  17. +7 −0 docs/publish.sh
  18. +1 −0 docs/title
  19. +3 −0 requirements.txt
View
@@ -0,0 +1,20 @@
+Copyright (c) 2012 Steve Losh and contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.**
+
+
View
@@ -0,0 +1,4 @@
+d
+=
+
+[Read the docs](http://sjl.bitbucket.org/d/).
View
13 bin/d
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+import sys, os
+
+# Ugly hack so I can code in peace.
+try:
+ from d.base import main
+except ImportError:
+ sys.path.append(os.path.abspath(os.path.join(__file__, '..', '..')))
+ from d.base import main
+
+if __name__ == '__main__':
+ main()
View
No changes.
View
197 d/base.py
@@ -0,0 +1,197 @@
+import sys, os, shutil
+import markdown
+from pyquery import PyQuery as pq
+
+
+j = os.path.join
+md = markdown.Markdown(extensions=['toc', 'codehilite'])
+up = lambda p: j(*os.path.split(p)[:-1])
+dirname = lambda p: os.path.basename(os.path.abspath(p))
+
+BUILD_LOC = './build'
+INDEX_PRE = '''\
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>{title_tag}</title>
+ <link rel="stylesheet" href="./_dmedia/bootstrap.css"/>
+ <link rel="stylesheet" href="./_dmedia/tango.css"/>
+ <link rel="stylesheet/less" type="text/css" href="./_dmedia/style.less">
+ <script src="./_dmedia/less.js" type="text/javascript">
+ </script>
+ </head>
+ <body class="index">
+ <div class="wrap">
+ <header><h1><a href="">{project_title}</a></h1></header>
+'''
+CONTENT_PRE = '''\
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>{title_tag}</title>
+ <link rel="stylesheet" href="../_dmedia/bootstrap.css"/>
+ <link rel="stylesheet" href="../_dmedia/tango.css"/>
+ <link rel="stylesheet/less" type="text/css" href="../_dmedia/style.less">
+ <script src="../_dmedia/less.js" type="text/javascript">
+ </script>
+ </head>
+ <body class="content">
+ <div class="wrap">
+ <header><h1><a href="..">{project_title}</a></h1></header>
+'''
+POST = '''
+ <footer>{footer}</footer>
+ </div>
+ </body>
+</html>
+'''
+
+
+def _get_target_url(path):
+ return os.path.split(_get_target(path))[-1]
+
+def _get_target(path):
+ parts = path.split('-', 1)
+
+ if len(parts) > 1 and all(c in '0123456789' for c in parts[0]):
+ target = parts[1]
+ else:
+ target = path
+
+ return j(BUILD_LOC, target.rsplit('.', 1)[0])
+
+def _get_project_title():
+ if os.path.isfile('title'):
+ with open('title') as f:
+ return f.read().strip()
+ else:
+ current = dirname('.').lower()
+ if current not in ['doc', 'docs', 'documentation']:
+ return current
+ else:
+ return dirname('..').lower()
+
+def _find_chapters():
+ for filename in os.listdir('.'):
+ name, ext = os.path.splitext(filename)
+ if ext in ['.markdown', '.md', '.mdown']:
+ if name not in ['footer', 'index']:
+ yield filename
+
+def _copy_raw_file(filename):
+ shutil.copyfile(j(up(__file__), filename),
+ j(BUILD_LOC, '_dmedia', filename))
+
+def _get_footer():
+ if os.path.isfile('./footer.markdown'):
+ with open('./footer.markdown') as f:
+ return md.convert(f.read())
+ elif os.path.isfile('./footer.mdown'):
+ with open('./footer.mdown') as f:
+ return md.convert(f.read())
+ elif os.path.isfile('./footer.md'):
+ with open('./footer.md') as f:
+ return md.convert(f.read())
+ else:
+ return ''
+
+def _get_toc(chapters):
+ toc = '<h2>Table of Contents</h2>'
+ toc += '<ol class="toc">'
+
+ for filename, title in chapters:
+ toc += '<li><a href="%s/">%s</a></li>' % (_get_target_url(filename), title)
+
+ toc += '</ol>'
+
+ return toc
+
+def _fix_md_toc(content):
+ """Remove the first heading level from the Markdown-generated TOC."""
+ e = pq(content)
+ if not e('.toc'):
+ return content
+
+ subtoc = e('.toc > ul > li > ul').html()
+ e('.toc > ul').html(subtoc)
+ return unicode(e)
+
+def _ensure_dir(path):
+ if not os.path.isdir(path):
+ os.makedirs(path)
+
+def _render(title, footer, path, target, page_type, toc=None):
+ if page_type == 'index':
+ pre, post = INDEX_PRE, POST
+ else:
+ pre, post = CONTENT_PRE, POST
+
+ with open(path) as f:
+ data = f.read()
+
+ if page_type == 'content':
+ page_title = data.splitlines()[0].lstrip('#').strip()
+ title_tag = page_title + ' / ' + title
+ else:
+ page_title = title_tag = title
+
+ content = pre.format(title_tag=title_tag, project_title=title)
+ content += md.convert(data)
+ content += toc or ''
+ content += post.format(footer=footer)
+
+ if page_type == 'content':
+ content = _fix_md_toc(content)
+
+ if not os.path.isdir(target):
+ os.makedirs(target)
+
+ with open(j(target, 'index.html'), 'w') as f:
+ f.write(content)
+
+ return page_title
+
+
+def render_chapter(title, footer, path):
+ target = _get_target(path)
+ return _render(title, footer, path, target, 'content')
+
+def render_index(title, footer, chapters):
+ if os.path.isfile('index.markdown'):
+ path = 'index.markdown'
+ elif os.path.isfile('index.mdown'):
+ path = 'index.mdown'
+ elif os.path.isfile('index.md'):
+ path = 'index.md'
+ else:
+ return
+
+ target = BUILD_LOC
+ toc = _get_toc(chapters)
+
+ return _render(title, footer, path, target, 'index', toc)
+
+def render_files():
+ _ensure_dir(BUILD_LOC)
+ _ensure_dir(j(BUILD_LOC, '_dmedia'))
+
+ title = _get_project_title()
+ footer = _get_footer()
+
+ map(_copy_raw_file, ['bootstrap.css', 'style.less', 'less.js', 'tango.css'])
+
+ chapters = []
+ for filename in _find_chapters():
+ chapter_title = render_chapter(title, footer, filename)
+ chapters.append((filename, chapter_title))
+
+ render_index(title, footer, chapters)
+
+
+def main():
+ if len(sys.argv) > 1:
+ sys.stderr.write("d doesn't take any arguments.\n")
+ sys.stderr.write("Just cd into your docs/ directory, run d, and move on.\n")
+ sys.exit(1)
+ else:
+ render_files()
Oops, something went wrong.

0 comments on commit dcdca5d

Please sign in to comment.