import sys, os, re, errno import markdown import simplejson as json import cgi from cuddlefish import packaging from cuddlefish import Bunch from cuddlefish.docs import apiparser from cuddlefish.docs import apirenderer from cuddlefish._version import get_versions INDEX_PAGE = '/doc/static-files/base.html' BASE_URL_INSERTION_POINT = '\n' return result def is_high_level(package_json): return not is_low_level(package_json) def is_low_level(package_json): return 'jetpack-low-level' in package_json.get('keywords', []) def insert_after(target, insertion_point_id, text_to_insert): insertion_point = target.find(insertion_point_id) + len(insertion_point_id) return target[:insertion_point] + text_to_insert + target[insertion_point:] class WebDocs(object): def __init__(self, root, base_url = '/'): self.root = root self.pkg_cfg = packaging.build_pkg_cfg(root) self.packages_json = packaging.build_pkg_index(self.pkg_cfg) self.base_page = self._create_base_page(root, base_url) def create_guide_page(self, path): path, ext = os.path.splitext(path) md_path = path + '.md' md_content = unicode(open(md_path, 'r').read(), 'utf8') guide_content = markdown.markdown(md_content) return self._create_page(guide_content) def create_module_page(self, path): path, ext = os.path.splitext(path) md_path = path + '.md' module_content = apirenderer.md_to_div(md_path) return self._create_page(module_content) def create_package_page(self, package_name): package_content = self._create_package_detail(package_name) return self._create_page(package_content) def _create_page(self, page_content): page = self._insert_title(self.base_page, page_content) page = insert_after(page, CONTENT_ID, page_content) return page.encode('utf8') def _create_module_list(self, package_json): package_name = package_json['name'] libs = package_json['files'][1]['lib'][1] doc_path = package_json.get('doc', None) if not doc_path: return '' modules = get_documented_modules(package_name, libs, doc_path) modules.sort() module_items = '' relative_doc_path = doc_path[len(self.root) + 1:] relative_doc_URL = "/".join(relative_doc_path.split(os.sep)) for module in modules: module_link = tag_wrap('/'.join(module), 'a', \ {'href': relative_doc_URL + '/' + '/'.join(module) + '.html'}) module_items += tag_wrap(module_link, 'li', {'class':'module'}) return tag_wrap(module_items, 'ul', {'class':'modules'}) def _create_package_summaries(self, packages_json, include): packages = '' for package_name in packages_json.keys(): package_json = packages_json[package_name] if not include(package_json): continue package_path = self.pkg_cfg["packages"][package_name]["root_dir"] package_directory = package_path[len(self.root) + 1:] package_directory = "/".join(package_directory.split(os.sep)) package_link = tag_wrap(package_name, 'a', {'href': \ package_directory + "/" \ + package_name + '.html'}) text = tag_wrap(package_link, 'h4') text += self._create_module_list(package_json) packages += tag_wrap(text, 'div', {'class':'package-summary', \ 'style':'display: block;'}) return packages def _create_base_page(self, root, base_url): base_page = unicode(open(root + INDEX_PAGE, 'r').read(), 'utf8') base_tag = 'href="' + base_url + '"' base_page = insert_after(base_page, BASE_URL_INSERTION_POINT, base_tag) sdk_version = get_versions()["version"] base_page = insert_after(base_page, VERSION_INSERTION_POINT, "Version " + sdk_version) high_level_summaries = \ self._create_package_summaries(self.packages_json, is_high_level) base_page = insert_after(base_page, \ HIGH_LEVEL_PACKAGE_SUMMARIES, high_level_summaries) low_level_summaries = \ self._create_package_summaries(self.packages_json, is_low_level) base_page = insert_after(base_page, \ LOW_LEVEL_PACKAGE_SUMMARIES, low_level_summaries) return base_page def _create_package_detail_row(self, field_value, \ field_descriptor, field_name): meta = tag_wrap(tag_wrap(field_descriptor, 'span', \ {'class':'meta-header'}), 'td') value = tag_wrap(tag_wrap(field_value, 'span', \ {'class':field_name}), 'td') return tag_wrap(meta + value, 'tr') def _create_package_detail_table(self, package_json): table_contents = '' if package_json.get('author', None): table_contents += self._create_package_detail_row(\ cgi.escape(package_json['author']), 'Author', 'author') if package_json.get('version', None): table_contents += self._create_package_detail_row(\ package_json['version'], 'Version', 'version') if package_json.get('license', None): table_contents += self._create_package_detail_row(\ package_json['license'], 'License', 'license') if package_json.get('dependencies', None): table_contents += self._create_package_detail_row(\ ', '.join(package_json['dependencies']), \ 'Dependencies', 'dependencies') table_contents += self._create_package_detail_row(\ self._create_module_list(package_json), 'Modules', 'modules') return tag_wrap(tag_wrap(table_contents, 'tbody'), 'table', \ {'class':'meta-table'}) def _create_package_detail(self, package_name): package_json = self.packages_json.get(package_name, None) if not package_json: raise IOError(errno.ENOENT, 'Package not found') # pieces of the package detail: 1) title, 2) table, 3) description package_title = tag_wrap(package_name, 'h1') table = self._create_package_detail_table(package_json) description = '' if package_json.get('readme', None): description += tag_wrap(tag_wrap(\ markdown.markdown(\ package_json['readme']), 'p'), 'div', {'class':'docs'}) return tag_wrap(package_title + table + description, 'div', \ {'class':'package-detail'}) def _insert_title(self, target, content): match = re.search('

.*

', content) if match: title = match.group(0)[len('

'):-len('

')] + ' - ' + \ DEFAULT_TITLE else: title = DEFAULT_TITLE target = insert_after(target, TITLE_ID, title) return target