Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1221)

Side by Side Diff: tools/md_browser/md_browser.py

Issue 2476133002: Add support for opening MD files directly in md_browser. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
18 import time
19 import webbrowser
17 20
18 21
19 THIS_DIR = os.path.abspath(os.path.dirname(__file__)) 22 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
20 SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR)) 23 SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR))
21 sys.path.append(os.path.join(SRC_DIR, 'third_party', 'Python-Markdown')) 24 sys.path.append(os.path.join(SRC_DIR, 'third_party', 'Python-Markdown'))
22 import markdown 25 import markdown
23 26
24 27
25 def main(argv): 28 def main(argv):
26 parser = argparse.ArgumentParser(prog='md_browser') 29 parser = argparse.ArgumentParser(prog='md_browser')
27 parser.add_argument('-p', '--port', type=int, default=8080, 30 parser.add_argument('-p', '--port', type=int, default=8080,
28 help='port to run on (default = %(default)s)') 31 help='port to run on (default = %(default)s)')
29 parser.add_argument('-d', '--directory', type=str, default=SRC_DIR) 32 parser.add_argument('-d', '--directory', type=str, default=SRC_DIR)
33 parser.add_argument('file', nargs='?',
34 help='open file in browser')
30 args = parser.parse_args(argv) 35 args = parser.parse_args(argv)
31 36
37 top_level = os.path.abspath(args.directory)
38
39 s = Server(args.port, top_level)
40
41 print('Listening on http://localhost:%s/' % args.port)
42 thread = None
43 if args.file:
44 path = os.path.abspath(args.file)
45 if not path.startswith(top_level):
46 print('%s is not under %s' % (args.file, args.directory))
47 return 1
48 rpath = os.path.relpath(path, top_level)
49 url = 'http://localhost:%d/%s' % (args.port, rpath)
50 print('Opening %s' % url)
51 thread = threading.Thread(target=_open_url, args=(url,))
52 thread.start()
53
54 elif os.path.isfile(os.path.join(top_level, 'docs', 'README.md')):
55 print(' Try loading http://localhost:%d/docs/README.md' % args.port)
56 elif os.path.isfile(os.path.join(args.directory, 'README.md')):
57 print(' Try loading http://localhost:%d/README.md' % args.port)
58
59 retcode = 1
32 try: 60 try:
33 s = Server(args.port, args.directory)
34 print("Listening on http://localhost:%s/" % args.port)
35 if os.path.isfile(os.path.join(args.directory, 'docs', 'README.md')):
36 print(" Try loading http://localhost:%s/docs/README.md" % args.port)
37 elif os.path.isfile(os.path.join(args.directory, 'README.md')):
38 print(" Try loading http://localhost:%s/README.md" % args.port)
39 s.serve_forever() 61 s.serve_forever()
40 s.shutdown()
41 return 0
42 except KeyboardInterrupt: 62 except KeyboardInterrupt:
43 return 130 63 retcode = 130
64 except Exception as e:
65 print('Exception raised: %s' % str(e))
66
67 s.shutdown()
68 if thread:
69 thread.join()
70 return retcode
71
72
73 def _open_url(url):
74 time.sleep(1)
75 webbrowser.open(url)
44 76
45 77
46 def _gitiles_slugify(value, _separator): 78 def _gitiles_slugify(value, _separator):
47 """Convert a string (representing a section title) to URL anchor name. 79 """Convert a string (representing a section title) to URL anchor name.
48 80
49 This function is passed to "toc" extension as an extension option, so we 81 This function is passed to "toc" extension as an extension option, so we
50 can emulate the way how Gitiles converts header titles to URL anchors. 82 can emulate the way how Gitiles converts header titles to URL anchors.
51 83
52 Gitiles' official documentation about the conversion is at: 84 Gitiles' official documentation about the conversion is at:
53 85
(...skipping 16 matching lines...) Expand all
70 value = value.replace(u' ', u'-') 102 value = value.replace(u' ', u'-')
71 value = re.sub(r'([-_])[-_]+', r'\1', value) # Fold hyphens and underscores. 103 value = re.sub(r'([-_])[-_]+', r'\1', value) # Fold hyphens and underscores.
72 return value 104 return value
73 105
74 106
75 class Server(SocketServer.TCPServer): 107 class Server(SocketServer.TCPServer):
76 def __init__(self, port, top_level): 108 def __init__(self, port, top_level):
77 SocketServer.TCPServer.__init__(self, ('0.0.0.0', port), Handler) 109 SocketServer.TCPServer.__init__(self, ('0.0.0.0', port), Handler)
78 self.port = port 110 self.port = port
79 self.top_level = os.path.abspath(top_level) 111 self.top_level = os.path.abspath(top_level)
112 self.retcode = None
80 113
81 def server_bind(self): 114 def server_bind(self):
82 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 115 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
83 self.socket.bind(self.server_address) 116 self.socket.bind(self.server_address)
84 117
85 118
86 class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): 119 class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
87 def do_GET(self): 120 def do_GET(self):
88 path = self.path 121 path = self.path
89 122
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 self.end_headers() 194 self.end_headers()
162 195
163 def _WriteTemplate(self, template): 196 def _WriteTemplate(self, template):
164 contents = self._Read(os.path.join('tools', 'md_browser', template), 197 contents = self._Read(os.path.join('tools', 'md_browser', template),
165 relative_to=SRC_DIR) 198 relative_to=SRC_DIR)
166 self.wfile.write(contents.encode('utf-8')) 199 self.wfile.write(contents.encode('utf-8'))
167 200
168 201
169 if __name__ == '__main__': 202 if __name__ == '__main__':
170 sys.exit(main(sys.argv[1:])) 203 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698