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

Unified 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, 5 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 side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/server2/converter.py
diff --git a/chrome/common/extensions/docs/server2/converter.py b/chrome/common/extensions/docs/server2/converter.py
new file mode 100755
index 0000000000000000000000000000000000000000..6c8fc85e4c20264435915045edabd2444678f37f
--- /dev/null
+++ b/chrome/common/extensions/docs/server2/converter.py
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Example run from the server2/ directory:
+# $ converter.py ../static/ ../../api templates/articles/ templates/intros/
+# templates/public/ static/images/ -r
+
+import optparse
+import os
+import re
+import shutil
+
+IGNORED_FILES = [
+ '404',
+ 'api_index',
+ 'experimental',
+ 'samples',
+ 'index'
+]
+
+def _UnixName(name):
+ """Returns the unix_style name for a given lowerCamelCase string.
+ Shamelessly stolen from json_schema_compiler/model.py.
+ """
+ name = os.path.splitext(name.split('/')[-1])[0]
+ s1 = re.sub('([a-z])([A-Z])', r'\1_\2', name)
+ s2 = re.sub('([A-Z]+)([A-Z][a-z])', r'\1_\2', s1)
+ return s2.replace('.', '_').lower()
+
+def _ReadFile(filename):
+ with open(filename, 'r') as f:
+ return f.read()
+
+def _WriteFile(filename, data):
+ with open(filename, 'w+') as f:
+ f.write(data)
+
+def _MakeArticleTemplate(filename):
+ return '{{+partials.standard_article article:intros.%s}}' % filename
+
+def _MakeAPITemplate(filename):
+ 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.
+ (filename, filename))
+
+def _FormatFile(contents, path, name, image_dest, replace, is_api):
+ # Copy all images referenced in the page.
+ for image in re.findall(r'src="\.\./images/([^"]*)"', contents):
+ if not replace and os.path.exists(os.path.join(image_dest, image)):
+ continue
+ if '/' in image:
+ try:
+ os.makedirs(os.path.join(image_dest, image.rsplit('/', 1)[0]))
+ except:
+ pass
+ shutil.copy(
+ os.path.join(path, os.pardir, 'images', image),
+ os.path.join(image_dest, image))
+ 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.
+ contents = re.sub(r'\.\./images', r'{{static}}/images', contents)
+ if is_api:
+ contents = re.sub(r'<div.*id="pageData-name".*>.*</div>', r'', contents)
+ else:
+ contents = re.sub(r'<div.*id="pageData-name".*>(.*)</div>',
+ r'<h1 class="page_title">\1</h1>',
+ contents)
+ # Remove blank lines.
+ contents = '\n'.join([line for line in contents.split('\n') if line.strip()])
+
+ # Attempt to guess if the page has no title.
+ if '<h1' not in contents and not is_api:
+ title = _UnixName(name)
+ title = ' '.join([part[0].upper() + part[1:] for part in title.split('_')])
+ contents = ('<h1 class="page_title">%s</h1>' % title) + contents
+ return contents
+
+def _MoveAllFiles(source_dir,
+ api_dir,
+ articles_dest,
+ intros_dest,
+ template_dest,
+ image_dest,
+ replace=False,
+ exclude_dir=None):
+ if exclude_dir is None:
+ exclude_files = []
+ else:
+ exclude_files = [_UnixName(f) for f in os.listdir(exclude_dir)]
+ exclude_files.extend(IGNORED_FILES)
+ if replace:
+ _CleanAPIs(source_dir, api_dir, intros_dest, template_dest, exclude_files)
+ for file_ in os.listdir(source_dir):
+ if _UnixName(file_) in exclude_files or file_.startswith('.'):
+ continue
+ _MoveSingleFile(source_dir,
+ file_,
+ api_dir,
+ articles_dest,
+ intros_dest,
+ template_dest,
+ image_dest,
+ replace)
+
+def _CleanAPIs(source_dir, api_dir, intros_dest, template_dest, exclude):
+ source_files = set(_UnixName(f) for f in os.listdir(source_dir))
+ api_files = set(_UnixName(f) for f in os.listdir(api_dir))
+ intros_files = set(_UnixName(f) for f in os.listdir(intros_dest))
+ to_delete = intros_files - source_files - set(exclude)
+ for filename in os.listdir(intros_dest):
+ if _UnixName(filename) in to_delete:
+ os.remove(os.path.join(intros_dest, filename))
+ os.remove(os.path.join(template_dest, filename))
+
+def _MoveSingleFile(source_dir,
+ source_file,
+ api_dir,
+ articles_dest,
+ intros_dest,
+ template_dest,
+ image_dest,
+ replace=False):
+ unix_name = _UnixName(source_file)
+ is_api = unix_name in [_UnixName(f) for f in os.listdir(api_dir)]
+ processed_name = os.path.splitext(source_file)[0].replace('.', '_')
+ static_data = _FormatFile(_ReadFile(os.path.join(source_dir, source_file)),
+ source_dir,
+ source_file,
+ image_dest,
+ replace,
+ is_api)
+ template_file = os.path.join(template_dest, processed_name + '.html')
+ if is_api:
+ template_data = _MakeAPITemplate(unix_name)
+ static_file = os.path.join(intros_dest, processed_name + '.html')
+ else:
+ template_data = _MakeArticleTemplate(unix_name)
+ static_file = os.path.join(articles_dest, processed_name + '.html')
+ if replace or not os.path.exists(template_file):
+ _WriteFile(template_file, template_data)
+ if replace or not os.path.exists(static_file):
+ _WriteFile(static_file, static_data)
+
+if __name__ == '__main__':
+ parser = optparse.OptionParser(
+ description='Converts static files from the old documentation system to '
+ 'the new one. If run without -f, all the files in |src| will '
+ 'be converted.',
+ usage='usage: %prog [options] static_src_dir [-f static_src_file] '
+ 'api_dir articles_dest intros_dest template_dest image_dest')
+ parser.add_option('-f',
+ '--file',
+ action='store_true',
+ default=False,
+ help='convert single file')
+ parser.add_option('-e',
+ '--exclude',
+ default=None,
+ help='exclude files matching the names in this dir')
+ parser.add_option('-r',
+ '--replace',
+ action='store_true',
+ default=False,
+ help='replace existing files')
+ (opts, args) = parser.parse_args()
+ if (not opts.file and len(args) != 6) or (opts.file and len(args) != 7):
+ parser.error('incorrect number of arguments.')
+
+ if opts.file:
+ _MoveSingleFile(*args, replace=opts.replace)
+ else:
+ _MoveAllFiles(*args, replace=opts.replace, exclude_dir=opts.exclude)

Powered by Google App Engine
This is Rietveld 408576698