Files
tubestation/addon-sdk/source/python-lib/cuddlefish/docs/documentationitem.py

165 lines
6.5 KiB
Python
Executable File

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import sys, os, re, simplejson
class DocumentationItemInfo(object):
def __init__(self, env_root, md_path, filename):
self.env_root = env_root
# full path to MD file, without filename
self.source_path = md_path
# MD filename
self.source_filename = filename
def env_root(self):
return self.env_root
def source_path(self):
return self.source_path
def source_filename(self):
return self.source_filename
def base_filename(self):
return self.source_filename[:-len(".md")]
def source_path_and_filename(self):
return os.sep.join([self.source_path, self.source_filename])
def source_path_relative_from_env_root(self):
return self.source_path[len(self.env_root) + 1:]
class DevGuideItemInfo(DocumentationItemInfo):
def __init__(self, env_root, devguide_root, md_path, filename):
DocumentationItemInfo.__init__(self, env_root, md_path, filename)
self.devguide_root = devguide_root
def source_path_relative_from_devguide_root(self):
return self.source_path[len(self.devguide_root) + 1:]
def destination_path(self):
root_pieces = self.devguide_root.split(os.sep)
root_pieces[-1] = "dev-guide"
return os.sep.join([os.sep.join(root_pieces), self.source_path_relative_from_devguide_root()])
class ModuleInfo(DocumentationItemInfo):
def __init__(self, env_root, module_root, md_path, filename):
DocumentationItemInfo.__init__(self, env_root, md_path, filename)
self.module_root = module_root
self.metadata = self.get_metadata()
def remove_comments(self, text):
def replacer(match):
s = match.group(0)
if s.startswith('/'):
return ""
else:
return s
pattern = re.compile(
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE
)
return re.sub(pattern, replacer, text)
def get_metadata(self):
if self.level() == "third-party":
return simplejson.loads("{}")
try:
js = unicode(open(self.js_module_path(),"r").read(), 'utf8')
except IOError:
raise Exception, "JS module: '" + path_to_js + \
"', corresponding to documentation file: '"\
+ self.source_path_and_filename() + "' wasn't found"
js = self.remove_comments(js)
js_lines = js.splitlines(True)
metadata = ''
reading_metadata = False
for line in js_lines:
if reading_metadata:
if line.startswith("};"):
break
metadata += line
continue
if line.startswith("module.metadata"):
reading_metadata = True
metadata = metadata.replace("'", '"')
return simplejson.loads("{" + metadata + "}")
def source_path_relative_from_module_root(self):
return self.source_path[len(self.module_root) + 1:]
def destination_path(self):
if self.level() == "third-party":
return os.sep.join([self.env_root, "doc", "modules", "packages"])
root_pieces = self.module_root.split(os.sep)
root_pieces[-1] = "modules"
relative_pieces = self.source_path_relative_from_module_root().split(os.sep)
return os.sep.join(root_pieces + relative_pieces)
def js_module_path(self):
return os.path.join(self.env_root, "lib", \
self.source_path_relative_from_module_root(), \
self.source_filename[:-len(".md")] + ".js")
def relative_url(self):
if self.level() == "third-party":
relative_pieces = ["packages"]
else:
relative_pieces = self.source_path_relative_from_module_root().split(os.sep)
return "/".join(relative_pieces) + "/" + self.base_filename() + ".html"
def name(self):
if os.sep.join([self.module_root, "sdk"]) == self.source_path or self.level() == "third-party":
return self.source_filename[:-3]
else:
path_from_root_pieces = self.source_path_relative_from_module_root().split(os.sep)
return "/".join(["/".join(path_from_root_pieces[1:]), self.source_filename[:-len(".md")]])
def level(self):
if self.source_path_relative_from_env_root().startswith("packages"):
return "third-party"
else:
if os.sep.join([self.module_root, "sdk"]) == self.source_path:
return "high"
else:
return "low"
def get_modules_in_package(env_root, package_docs_dir, module_list, ignore_files_in_root):
for (dirpath, dirnames, filenames) in os.walk(package_docs_dir):
for filename in filenames:
# ignore files in the root
if ignore_files_in_root and package_docs_dir == dirpath:
continue
if filename.endswith(".md"):
module_list.append(ModuleInfo(env_root, package_docs_dir, dirpath, filename))
def get_module_list(env_root):
module_list = []
# get the built-in modules
module_root = os.sep.join([env_root, "doc", "module-source"])
get_modules_in_package(env_root, module_root, module_list, True)
# get the third-party modules
packages_root = os.sep.join([env_root, "packages"])
if os.path.exists(packages_root):
for entry in os.listdir(packages_root):
if os.path.isdir(os.sep.join([packages_root, entry])):
package_docs = os.sep.join([packages_root, entry, "docs"])
if os.path.exists(package_docs):
get_modules_in_package(env_root, package_docs, module_list, False)
module_list.sort(key=lambda x: x.name())
return module_list
def get_devguide_list(env_root):
devguide_list = []
devguide_root = os.sep.join([env_root, "doc", "dev-guide-source"])
for (dirpath, dirnames, filenames) in os.walk(devguide_root):
for filename in filenames:
if filename.endswith(".md"):
devguide_list.append(DevGuideItemInfo(env_root, devguide_root, dirpath, filename))
return devguide_list
if __name__ == "__main__":
module_list = get_module_list(sys.argv[1])
print [module_info.name for module_info in module_list]