165 lines
6.5 KiB
Python
Executable File
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]
|