1 #!/usr/bin/env python 2 3 # Copyright (C) 2011 The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 import codecs 18 import glob 19 import markdown 20 import os 21 import shutil 22 import string 23 import subprocess 24 25 26 # read just the title (first heading) from a source page 27 def get_title(raw_file): 28 for line in open(raw_file, 'r'): 29 if '#' in line: 30 return line.strip(' #\n') 31 return '' 32 33 34 # directory to compile the site to (will be clobbered during build!) 35 HTML_DIR = 'out' 36 # directory to look in for markdown source files 37 SRC_DIR = 'src' 38 # directory to look in for html templates 39 TEMPLATE_DIR = 'templates' 40 41 # filenames of templates to load, in order 42 TEMPLATE_LIST = ['includes', 'header', 'sidebar', 'main', 'footer'] 43 44 # Step 1, concatenate the template pieces into a single template string 45 t = '' 46 for f in TEMPLATE_LIST: 47 t += open(os.path.join(TEMPLATE_DIR, f), 'r').read() 48 template = string.Template(t) 49 50 # Step 2, rm -rf HTML_DIR if it exists, and then re-create it 51 if os.path.exists(HTML_DIR): 52 shutil.rmtree(HTML_DIR) 53 54 os.mkdir(HTML_DIR) 55 56 # Step 3, recursively mirror SRC_DIR to HTML_DIR, directory by directory, translating *.md 57 category = 'home' 58 parents = {} 59 for curdir, subdirs, files in os.walk(SRC_DIR): 60 def md(path): 61 text = codecs.open(path, encoding='utf8').read() 62 extensions = ['tables', 'def_list', 'toc(title=In This Document)'] 63 return markdown.markdown(text, extensions) 64 65 print 'Processing %s...' % (curdir,), 66 # Step A: split path, and update cached category name if needed 67 curdir = os.path.normpath(curdir) 68 outdir = curdir.split(os.path.sep) 69 outdir[0] = HTML_DIR 70 if len(outdir) == 2: 71 category = outdir[-1] 72 outdir = os.path.join(*outdir) 73 74 # Step B: mirror the hierarchy of immediate subdirectories 75 for subdir in subdirs: 76 os.mkdir(os.path.join(outdir, subdir)) 77 78 # Step C: cache the translated sidebars, keyed by parent dir, so we can do sidebar inheritance 79 # FIXME: make this depth-agnostic, perhaps by caching all sidebars and moving the resolution 80 # FIXME: complexity out of the datastructure and into the resolution algorithm. 81 parentdir = os.path.dirname(curdir) 82 if parentdir in parents: 83 parent = parents[parentdir] 84 else: 85 parent = ('', '', '') 86 87 if 'sidebar.md' in files: 88 sidebar = md(os.path.join(curdir, 'sidebar.md')) 89 del files[files.index('sidebar.md')] 90 else: 91 sidebar = parent[0] 92 93 if 'sidebar2.md' in files: 94 sidebar2 = md(os.path.join(curdir, 'sidebar2.md')) 95 del files[files.index('sidebar2.md')] 96 else: 97 sidebar2 = parent[1] 98 99 if 'sidebar3.md' in files: 100 sidebar3 = md(os.path.join(curdir, 'sidebar3.md')) 101 del files[files.index('sidebar3.md')] 102 else: 103 sidebar3 = parent[2] 104 105 parents[curdir] = (sidebar, sidebar2, sidebar3) 106 107 # Step D: mirror all non-*.md files, and translate (file).md files into (file).html 108 for f in files: 109 print ' .', 110 # Note that this "absolute" filename has a root at SRC_DIR, not "/" 111 absfilename = os.path.join(curdir, f) 112 113 if f.endswith('.md'): 114 main = md(absfilename) 115 final = template.safe_substitute(main=main, sidebar=sidebar, sidebar2=sidebar2, \ 116 sidebar3=sidebar3, category=category, title=get_title(absfilename)) 117 118 html = codecs.open(os.path.join(outdir, f.replace('.md', '.html')), 'w', encoding="utf8") 119 html.write(final) 120 else: 121 shutil.copy(absfilename, os.path.join(outdir, f)) 122 print 123 124 print 'Done.' 125