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

Side by Side Diff: chrome/common/extensions/docs/server2/converter.py

Issue 10832042: Extensions Docs Server: Doc conversion script (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix comment in converter.py Created 8 years, 4 months 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 # Example run from the server2/ directory:
7 # $ converter.py ../static/ ../../api templates/articles/ templates/intros/
8 # templates/public/ static/images/ -r
9
10 import optparse
11 import os
12 import re
13 import shutil
14
15 IGNORED_FILES = [
16 '404',
17 'api_index',
18 'experimental',
19 'samples',
20 'index'
21 ]
22
23 def _UnixName(name):
24 """Returns the unix_style name for a given lowerCamelCase string.
25 Shamelessly stolen from json_schema_compiler/model.py.
26 """
27 name = os.path.splitext(name.split('/')[-1])[0]
28 s1 = re.sub('([a-z])([A-Z])', r'\1_\2', name)
29 s2 = re.sub('([A-Z]+)([A-Z][a-z])', r'\1_\2', s1)
30 return s2.replace('.', '_').lower()
31
32 def _ReadFile(filename):
33 with open(filename, 'r') as f:
34 return f.read()
35
36 def _WriteFile(filename, data):
37 with open(filename, 'w+') as f:
38 f.write(data)
39
40 def _MakeArticleTemplate(filename):
41 return '{{+partials.standard_article article:intros.%s}}' % filename
42
43 def _MakeAPITemplate(filename):
44 return ('{{+partials.standard_api api:apis.%s intro:intros.%s}}' %
not at google - send to devlin 2012/07/31 22:25:46 some APIs don't have intros, like fileSystem that
cduvall 2012/08/01 01:40:50 Done.
45 (filename, filename))
46
47 def _FormatFile(contents, path, name, image_dest, replace, is_api):
48 # Copy all images referenced in the page.
49 for image in re.findall(r'src="\.\./images/([^"]*)"', contents):
50 if not replace and os.path.exists(os.path.join(image_dest, image)):
51 continue
52 if '/' in image:
53 try:
54 os.makedirs(os.path.join(image_dest, image.rsplit('/', 1)[0]))
55 except:
56 pass
57 shutil.copy(
58 os.path.join(path, os.pardir, 'images', image),
59 os.path.join(image_dest, image))
60 contents = re.sub(r'<!--.*-->', r'', contents)
not at google - send to devlin 2012/07/31 22:25:46 I don't think we want to delete *all* comments. Ju
cduvall 2012/08/01 01:40:50 Done.
61 contents = re.sub(r'\.\./images', r'{{static}}/images', contents)
62 if is_api:
63 contents = re.sub(r'<div.*id="pageData-name".*>.*</div>', r'', contents)
64 else:
65 contents = re.sub(r'<div.*id="pageData-name".*>(.*)</div>',
66 r'<h1 class="page_title">\1</h1>',
67 contents)
68 # Remove blank lines.
69 contents = '\n'.join([line for line in contents.split('\n') if line.strip()])
70
71 # Attempt to guess if the page has no title.
72 if '<h1' not in contents and not is_api:
73 title = _UnixName(name)
74 title = ' '.join([part[0].upper() + part[1:] for part in title.split('_')])
75 contents = ('<h1 class="page_title">%s</h1>' % title) + contents
76 return contents
77
78 def _MoveAllFiles(source_dir,
79 api_dir,
80 articles_dest,
81 intros_dest,
82 template_dest,
83 image_dest,
84 replace=False,
85 exclude_dir=None):
86 if exclude_dir is None:
87 exclude_files = []
88 else:
89 exclude_files = [_UnixName(f) for f in os.listdir(exclude_dir)]
90 exclude_files.extend(IGNORED_FILES)
91 if replace:
92 _CleanAPIs(source_dir, api_dir, intros_dest, template_dest, exclude_files)
93 for file_ in os.listdir(source_dir):
94 if _UnixName(file_) in exclude_files or file_.startswith('.'):
95 continue
96 _MoveSingleFile(source_dir,
97 file_,
98 api_dir,
99 articles_dest,
100 intros_dest,
101 template_dest,
102 image_dest,
103 replace)
104
105 def _CleanAPIs(source_dir, api_dir, intros_dest, template_dest, exclude):
106 source_files = set(_UnixName(f) for f in os.listdir(source_dir))
107 api_files = set(_UnixName(f) for f in os.listdir(api_dir))
108 intros_files = set(_UnixName(f) for f in os.listdir(intros_dest))
109 to_delete = intros_files - source_files - set(exclude)
110 for filename in os.listdir(intros_dest):
111 if _UnixName(filename) in to_delete:
112 os.remove(os.path.join(intros_dest, filename))
113 os.remove(os.path.join(template_dest, filename))
114
115 def _MoveSingleFile(source_dir,
116 source_file,
117 api_dir,
118 articles_dest,
119 intros_dest,
120 template_dest,
121 image_dest,
122 replace=False):
123 unix_name = _UnixName(source_file)
124 is_api = unix_name in [_UnixName(f) for f in os.listdir(api_dir)]
125 processed_name = os.path.splitext(source_file)[0].replace('.', '_')
126 static_data = _FormatFile(_ReadFile(os.path.join(source_dir, source_file)),
127 source_dir,
128 source_file,
129 image_dest,
130 replace,
131 is_api)
132 template_file = os.path.join(template_dest, processed_name + '.html')
133 if is_api:
134 template_data = _MakeAPITemplate(unix_name)
135 static_file = os.path.join(intros_dest, processed_name + '.html')
136 else:
137 template_data = _MakeArticleTemplate(unix_name)
138 static_file = os.path.join(articles_dest, processed_name + '.html')
139 if replace or not os.path.exists(template_file):
140 _WriteFile(template_file, template_data)
141 if replace or not os.path.exists(static_file):
142 _WriteFile(static_file, static_data)
143
144 if __name__ == '__main__':
145 parser = optparse.OptionParser(
146 description='Converts static files from the old documentation system to '
147 'the new one. If run without -f, all the files in |src| will '
148 'be converted.',
149 usage='usage: %prog [options] static_src_dir [-f static_src_file] '
150 'api_dir articles_dest intros_dest template_dest image_dest')
151 parser.add_option('-f',
152 '--file',
153 action='store_true',
154 default=False,
155 help='convert single file')
156 parser.add_option('-e',
157 '--exclude',
158 default=None,
159 help='exclude files matching the names in this dir')
160 parser.add_option('-r',
161 '--replace',
162 action='store_true',
163 default=False,
164 help='replace existing files')
165 (opts, args) = parser.parse_args()
166 if (not opts.file and len(args) != 6) or (opts.file and len(args) != 7):
167 parser.error('incorrect number of arguments.')
168
169 if opts.file:
170 _MoveSingleFile(*args, replace=opts.replace)
171 else:
172 _MoveAllFiles(*args, replace=opts.replace, exclude_dir=opts.exclude)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698