Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 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 | |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 17 | import os |
| 18 | import glob |
| 19 | import shutil |
| 20 | import string |
| 21 | import subprocess |
| 22 | |
| 23 | |
| 24 | # call markdown as a subprocess, and capture the output |
| 25 | def markdown(raw_file): |
Jeff Brown | 590a9d6 | 2011-06-30 12:55:34 -0700 | [diff] [blame] | 26 | extensions = '-x tables -x "toc(title=In This Document)" -x def_list' |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 27 | command = 'markdown' + ' ' + extensions + ' ' + raw_file |
| 28 | p = subprocess.Popen(command, stdout = subprocess.PIPE, shell = True) |
| 29 | return p.communicate()[0] |
| 30 | |
| 31 | |
| 32 | # read just the title (first heading) from a source page |
| 33 | def get_title(raw_file): |
| 34 | for line in open(raw_file, 'r'): |
| 35 | if '#' in line: |
| 36 | return line.strip(' #\n') |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 37 | return '' |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 38 | |
| 39 | |
| 40 | # directory to compile the site to (will be clobbered during build!) |
| 41 | HTML_DIR = 'out' |
| 42 | # directory to look in for markdown source files |
| 43 | SRC_DIR = 'src' |
| 44 | # directory to look in for html templates |
| 45 | TEMPLATE_DIR = 'templates' |
| 46 | |
| 47 | # filenames of templates to load, in order |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 48 | TEMPLATE_LIST = ['includes', 'header', 'sidebar', 'main', 'footer'] |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 49 | |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 50 | # Step 1, concatenate the template pieces into a single template string |
| 51 | t = '' |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 52 | for f in TEMPLATE_LIST: |
| 53 | t += open(os.path.join(TEMPLATE_DIR, f), 'r').read() |
| 54 | template = string.Template(t) |
| 55 | |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 56 | # Step 2, rm -rf HTML_DIR if it exists, and then re-create it |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 57 | if os.path.exists(HTML_DIR): |
| 58 | shutil.rmtree(HTML_DIR) |
| 59 | |
| 60 | os.mkdir(HTML_DIR) |
| 61 | |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 62 | # Step 3, recursively mirror SRC_DIR to HTML_DIR, directory by directory, translating *.md |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 63 | category = 'home' |
Jeff Brown | a049dde | 2011-06-29 16:51:54 -0700 | [diff] [blame] | 64 | parents = {} |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 65 | for curdir, subdirs, files in os.walk(SRC_DIR): |
| 66 | print 'Processing %s...' % (curdir,), |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 67 | # Step A: split path, and update cached category name if needed |
| 68 | curdir = os.path.normpath(curdir) |
| 69 | outdir = curdir.split(os.path.sep) |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 70 | outdir[0] = HTML_DIR |
| 71 | if len(outdir) == 2: |
| 72 | category = outdir[-1] |
| 73 | outdir = os.path.join(*outdir) |
Jeff Brown | a049dde | 2011-06-29 16:51:54 -0700 | [diff] [blame] | 74 | |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 75 | # Step B: mirror the hierarchy of immediate subdirectories |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 76 | for subdir in subdirs: |
| 77 | os.mkdir(os.path.join(outdir, subdir)) |
| 78 | |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 79 | # Step C: cache the translated sidebars, keyed by parent dir, so we can do sidebar inheritance |
| 80 | # FIXME: make this depth-agnostic, perhaps by caching all sidebars and moving the resolution |
| 81 | # FIXME: complexity out of the datastructure and into the resolution algorithm. |
Jeff Brown | a049dde | 2011-06-29 16:51:54 -0700 | [diff] [blame] | 82 | parentdir = os.path.dirname(curdir) |
| 83 | if parentdir in parents: |
| 84 | parent = parents[parentdir] |
| 85 | else: |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 86 | parent = ('', '', '') |
Jeff Brown | a049dde | 2011-06-29 16:51:54 -0700 | [diff] [blame] | 87 | |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 88 | if 'sidebar.md' in files: |
| 89 | sidebar = markdown(os.path.join(curdir, 'sidebar.md')) |
| 90 | del files[files.index('sidebar.md')] |
| 91 | else: |
Jeff Brown | a049dde | 2011-06-29 16:51:54 -0700 | [diff] [blame] | 92 | sidebar = parent[0] |
| 93 | |
| 94 | if 'sidebar2.md' in files: |
| 95 | sidebar2 = markdown(os.path.join(curdir, 'sidebar2.md')) |
| 96 | del files[files.index('sidebar2.md')] |
| 97 | else: |
| 98 | sidebar2 = parent[1] |
| 99 | |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 100 | if 'sidebar3.md' in files: |
| 101 | sidebar3 = markdown(os.path.join(curdir, 'sidebar3.md')) |
| 102 | del files[files.index('sidebar3.md')] |
| 103 | else: |
| 104 | sidebar3 = parent[2] |
Jeff Brown | a049dde | 2011-06-29 16:51:54 -0700 | [diff] [blame] | 105 | |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 106 | parents[curdir] = (sidebar, sidebar2, sidebar3) |
| 107 | |
| 108 | # Step D: mirror all non-*.md files, and translate (file).md files into (file).html |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 109 | for f in files: |
| 110 | print ' .', |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 111 | # Note that this "absolute" filename has a root at SRC_DIR, not "/" |
| 112 | absfilename = os.path.join(curdir, f) |
| 113 | |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 114 | if f.endswith('.md'): |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 115 | main = markdown(absfilename) |
Jeff Brown | a049dde | 2011-06-29 16:51:54 -0700 | [diff] [blame] | 116 | final = template.safe_substitute(main=main, sidebar=sidebar, sidebar2=sidebar2, \ |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 117 | sidebar3=sidebar3, category=category, title=get_title(absfilename)) |
| 118 | |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 119 | html = file(os.path.join(outdir, f.replace('.md', '.html')), 'w') |
| 120 | html.write(final) |
| 121 | else: |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 122 | shutil.copy(absfilename, os.path.join(outdir, f)) |
Skyler Kaufman | 991ae4d | 2011-04-07 12:30:41 -0700 | [diff] [blame] | 123 | print |
| 124 | |
| 125 | print 'Done.' |
Omari Stephens | bdac766 | 2011-12-13 16:51:27 -0800 | [diff] [blame] | 126 | |