Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Simple Markdown browser for a Git checkout.""" | 6 """Simple Markdown browser for a Git checkout.""" |
| 7 from __future__ import print_function | 7 from __future__ import print_function |
| 8 | 8 |
| 9 import SimpleHTTPServer | 9 import SimpleHTTPServer |
| 10 import SocketServer | 10 import SocketServer |
| 11 import argparse | 11 import argparse |
| 12 import codecs | 12 import codecs |
| 13 import os | 13 import os |
| 14 import re | 14 import re |
| 15 import socket | 15 import socket |
| 16 import sys | 16 import sys |
| 17 import threading | 17 import threading |
| 18 import time | 18 import time |
| 19 import webbrowser | 19 import webbrowser |
| 20 from xml.etree import ElementTree | |
| 20 | 21 |
| 21 | 22 |
| 22 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) | 23 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) |
| 23 SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR)) | 24 SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR)) |
| 24 sys.path.append(os.path.join(SRC_DIR, 'third_party', 'Python-Markdown')) | 25 sys.path.insert(0, os.path.join(SRC_DIR, 'third_party', 'Python-Markdown')) |
| 25 import markdown | 26 import markdown |
| 26 | 27 |
| 27 | 28 |
| 28 def main(argv): | 29 def main(argv): |
| 29 parser = argparse.ArgumentParser(prog='md_browser') | 30 parser = argparse.ArgumentParser(prog='md_browser') |
| 30 parser.add_argument('-p', '--port', type=int, default=8080, | 31 parser.add_argument('-p', '--port', type=int, default=8080, |
| 31 help='port to run on (default = %(default)s)') | 32 help='port to run on (default = %(default)s)') |
| 32 parser.add_argument('-d', '--directory', type=str, default=SRC_DIR) | 33 parser.add_argument('-d', '--directory', type=str, default=SRC_DIR) |
| 33 parser.add_argument('file', nargs='?', | 34 parser.add_argument('file', nargs='?', |
| 34 help='open file in browser') | 35 help='open file in browser') |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 'markdown.extensions.toc', | 149 'markdown.extensions.toc', |
| 149 'gitiles_ext_blocks', | 150 'gitiles_ext_blocks', |
| 150 ] | 151 ] |
| 151 extension_configs = { | 152 extension_configs = { |
| 152 'markdown.extensions.toc': { | 153 'markdown.extensions.toc': { |
| 153 'slugify': _gitiles_slugify | 154 'slugify': _gitiles_slugify |
| 154 }, | 155 }, |
| 155 } | 156 } |
| 156 | 157 |
| 157 contents = self._Read(path[1:]) | 158 contents = self._Read(path[1:]) |
| 158 md_fragment = markdown.markdown(contents, | 159 |
| 159 extensions=extensions, | 160 md = markdown.Markdown(extensions=extensions, |
| 160 extension_configs=extension_configs, | 161 extension_configs=extension_configs, |
| 161 output_format='html4').encode('utf-8') | 162 output_format='html4') |
| 163 md.treeprocessors['adjust_toc'] = _AdjustTOC() | |
| 164 | |
| 165 md_fragment = md.convert(contents).encode('utf-8') | |
| 166 | |
| 162 try: | 167 try: |
| 163 self._WriteHeader('text/html') | 168 self._WriteHeader('text/html') |
| 164 self._WriteTemplate('header.html') | 169 self._WriteTemplate('header.html') |
| 165 self.wfile.write(md_fragment) | 170 self.wfile.write(md_fragment) |
| 166 self._WriteTemplate('footer.html') | 171 self._WriteTemplate('footer.html') |
| 167 except: | 172 except: |
| 168 raise | 173 raise |
| 169 | 174 |
| 170 def _DoCSS(self, template): | 175 def _DoCSS(self, template): |
| 171 self._WriteHeader('text/css') | 176 self._WriteHeader('text/css') |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 192 self.send_response(200) | 197 self.send_response(200) |
| 193 self.send_header('Content-Type', content_type) | 198 self.send_header('Content-Type', content_type) |
| 194 self.end_headers() | 199 self.end_headers() |
| 195 | 200 |
| 196 def _WriteTemplate(self, template): | 201 def _WriteTemplate(self, template): |
| 197 contents = self._Read(os.path.join('tools', 'md_browser', template), | 202 contents = self._Read(os.path.join('tools', 'md_browser', template), |
| 198 relative_to=SRC_DIR) | 203 relative_to=SRC_DIR) |
| 199 self.wfile.write(contents.encode('utf-8')) | 204 self.wfile.write(contents.encode('utf-8')) |
| 200 | 205 |
| 201 | 206 |
| 207 | |
| 208 class _AdjustTOC(markdown.treeprocessors.Treeprocessor): | |
| 209 def run(self, tree): | |
| 210 # A table of contents with a single H1 header is translated to | |
| 211 # <div class='toc'> | |
| 212 # <ul> | |
| 213 # <li> | |
| 214 # <a>H1> | |
| 215 # <ul> | |
| 216 # <li>first H2 | |
| 217 # <li>second H2</li></ul></li><ul> | |
| 218 # | |
| 219 # We want to replace the first ul with the second one. | |
| 220 # | |
| 221 # Also, we want to insert an <h2>Contents and then indent | |
|
jsbell
2016/11/07 17:32:06
Can you depict the "after" structure as you did th
Dirk Pranke
2016/11/07 18:17:27
Will do.
| |
| 222 # the rest in a <div class='toc-aux'>. | |
| 223 toc_nodes = tree.findall(".//*[@class='toc']") | |
| 224 if toc_nodes: | |
|
jsbell
2016/11/07 17:32:06
Maybe early return if falsy, to reduce indentation
Dirk Pranke
2016/11/07 18:17:27
Good suggestion, will do.
| |
| 225 if len(toc_nodes) == 1: | |
| 226 toc = toc_nodes[0] | |
| 227 toc_ul = toc[0] | |
| 228 toc_ul_li = toc_ul[0] | |
| 229 toc_ul_li_ul = toc_ul_li[1] | |
| 230 del toc[0] | |
| 231 children = toc_ul_li_ul | |
| 232 else: | |
| 233 children = list(toc) | |
|
jsbell
2016/11/07 17:32:06
What is toc in this else branch, and below if this
Dirk Pranke
2016/11/07 18:17:27
See above, will fix.
| |
| 234 | |
| 235 while len(toc): | |
| 236 toc.remove[0] | |
| 237 contents = ElementTree.SubElement(toc, 'h2') | |
| 238 contents.text = 'Contents' | |
| 239 contents.tail = '\n' | |
| 240 toc_aux = ElementTree.SubElement(toc, 'div', attrib={'class': 'toc-aux'}) | |
| 241 toc_aux.text = '\n' | |
| 242 toc_aux_ul = ElementTree.SubElement(toc_aux, 'ul') | |
| 243 toc_aux_ul.text = '\n' | |
| 244 toc_aux_ul.extend(children) | |
| 245 toc_aux_ul.tail = '\n' | |
| 246 toc_aux.tail = '\n' | |
| 247 | |
| 248 | |
| 202 if __name__ == '__main__': | 249 if __name__ == '__main__': |
| 203 sys.exit(main(sys.argv[1:])) | 250 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |