def prepOutputDirectory(self): if not os.path.exists(self.base): os.mkdir(self.base) shutil.copyfile(templatefile('apidocs.css'), os.path.join(self.base, 'apidocs.css')) if self.system.options.htmlusesorttable: shutil.copyfile(templatefile('sorttable.js'), os.path.join(self.base, 'sorttable.js')) if self.system.options.htmlusesplitlinks or self.system.options.htmlshortenlists: shutil.copyfile(templatefile('pydoctor.js'), os.path.join(self.base, 'pydoctor.js'))
def __init__(self, system): self.system = system self.putChild('apidocs.css', File(util.templatefile('apidocs.css'))) self.putChild('sorttable.js', File(util.templatefile('sorttable.js'))) self.putChild('pydoctor.js', File(util.templatefile('pydoctor.js'))) self.index = WrapperPage(self.indexPage()) self.putChild('', self.index) self.putChild('index.html', self.index) self.putChild('moduleIndex.html', WrapperPage(summary.ModuleIndexPage(self.system))) self.putChild('classIndex.html', WrapperPage(summary.ClassIndexPage(self.system))) self.putChild('nameIndex.html', WrapperPage(summary.NameIndexPage(self.system)))
class UndocumentedSummaryPage(page.Element): filename = 'undoccedSummary.html' docFactory = loaders.xmlfile(templatefile('summary.html')) def __init__(self, system): self.system = system @page.renderer def title(self, request, tag): return tag.clear()["Summary of Undocumented Objects"] @page.renderer def heading(self, request, tag): return tag.clear()["Summary of Undocumented Objects"] @page.renderer def stuff(self, request, tag): undoccedpublic = [ o for o in self.system.orderedallobjects if o.isVisible and not hasdocstring(o) ] undoccedpublic.sort(key=lambda o: o.fullName()) for o in undoccedpublic: tag[tags.li[o.kind, " - ", taglink(o)]] return tag
class ChildTable(page.Element): docFactory = loaders.xmlfile(util.templatefile('table.html')) last_id = 0 def __init__(self, docgetter, ob, has_lineno_col, children): self.docgetter = docgetter self.system = ob.system self.has_lineno_col = has_lineno_col self.children = children ChildTable.last_id += 1 self._id = ChildTable.last_id self.ob = ob @page.renderer def id(self, request, tag): return 'id'+str(self._id) @page.renderer def header(self, request, tag): if self.system.options.htmlusesorttable: return tag else: return () @page.renderer def linenohead(self, request, tag): if self.has_lineno_col: return tag else: return () @page.renderer def rows(self, request, tag): return [TableRow(self.docgetter, self.has_lineno_col, self.ob, child) for child in self.children]
class ClassIndexPage(page.Element): filename = 'classIndex.html' docFactory = loaders.xmlfile(templatefile('summary.html')) def __init__(self, system): self.system = system @page.renderer def title(self, request, tag): return tag.clear()["Class Hierarchy"] @page.renderer def stuff(self, request, tag): t = tag anchors = set() for b, o in findRootClasses(self.system): if isinstance(o, model.Class): t[subclassesFrom(self.system, o, anchors)] else: item = tags.li[b] if o: ul = tags.ul() for sc in sorted(o, key=_lckey): ul[subclassesFrom(self.system, sc, anchors)] item[ul] t[item] return t @page.renderer def heading(self, request, tag): return tag.clear()["Class Hierarchy"]
class NameIndexPage(page.Element): filename = 'nameIndex.html' docFactory = loaders.xmlfile(templatefile('nameIndex.html')) def __init__(self, system): self.system = system @page.renderer def title(self, request, tag): return tag.clear()["Index Of Names"] @page.renderer def heading(self, request, tag): return tag.clear()["Index Of Names"] @page.renderer def index(self, request, tag): letter = tag.patternGenerator('letter') singleName = tag.patternGenerator('singleName') manyNames = tag.patternGenerator('manyNames') initials = {} for ob in self.system.orderedallobjects: if ob.isVisible: initials.setdefault(ob.name[0].upper(), []).append(ob) for initial in sorted(initials): letterlinks = [] for initial2 in sorted(initials): if initial == initial2: letterlinks.append(initial2) else: letterlinks.append(tags.a(href='#' + initial2)[initial2]) letterlinks.append(' - ') if letterlinks: del letterlinks[-1] name2obs = {} for obj in initials[initial]: name2obs.setdefault(obj.name, []).append(obj) lettercontents = [] for name in sorted(name2obs, key=lambda x: x.lower()): obs = sorted(name2obs[name], key=lambda x: x.fullName().lower()) if len(obs) == 1: ob, = obs lettercontents.append( fillSlots(singleName, name=ob.name, link=taglink(ob))) else: lettercontents.append( fillSlots( manyNames, name=obs[0].name, manyNames=[tags.li[taglink(ob)] for ob in obs])) tag[fillSlots(letter, letter=initial, letterlinks=letterlinks, lettercontents=lettercontents)] return tag
class FunctionChild(page.Element): docFactory = loaders.xmlfile(util.templatefile('function-child.html')) def __init__(self, docgetter, ob, functionExtras): self.docgetter = docgetter self.ob = ob self._functionExtras = functionExtras @page.renderer def functionAnchor(self, request, tag): return self.ob.fullName() @page.renderer def shortFunctionAnchor(self, request, tag): return self.ob.name @page.renderer def decorator(self, request, tag): if self.ob.decorators: decorators = [ast_pp.pp(dec) for dec in self.ob.decorators] else: decorators = [] if self.ob.kind == "Class Method" \ and 'classmethod' not in decorators: decorators.append('classmethod') elif self.ob.kind == "Static Method" \ and 'staticmethod' not in decorators: decorators.append('staticmethod') if decorators: decorator = [('@' + dec, tags.br()) for dec in decorators] else: decorator = () return decorator @page.renderer def functionName(self, request, tag): return [self.ob.name, '(', signature(self.ob.argspec), '):'] @page.renderer def sourceLink(self, request, tag): if self.ob.sourceHref: return tag.fillSlots('sourceHref', self.ob.sourceHref) else: return () @page.renderer def functionExtras(self, request, tag): return self._functionExtras @page.renderer def functionBody(self, request, tag): return self.docgetter.get(self.ob)
class ProblemObjectsPage(rend.Page): def __init__(self, system): self.system = system def render_problemObjects(self, context, data): t = context.tag pat = t.patternGenerator('object') for fn in sorted(self.system.epytextproblems): o = self.system.allobjects[fn] t[pat.fillSlots('link', util.taglink(o))] return t docFactory = loaders.xmlfile(util.templatefile('problemObjects.html'))
class ModuleIndexPage(page.Element): filename = 'moduleIndex.html' docFactory = loaders.xmlfile(templatefile('summary.html')) def __init__(self, system): self.system = system @page.renderer def title(self, request, tag): return tag.clear()["Module Index"] @page.renderer def stuff(self, request, tag): r = [] for o in self.system.rootobjects: r.append(moduleSummary(o)) return tag.clear()[r] @page.renderer def heading(self, request, tag): return tag().clear()["Module Index"]
class TableRow(page.Element): docFactory = loaders.xmlfile(util.templatefile('table.html'), 'row') def __init__(self, docgetter, has_lineno_col, ob, child): self.docgetter = docgetter self.has_lineno_col = has_lineno_col self.ob = ob self.child = child @page.renderer def class_(self, request, tag): class_ = self.child.css_class if self.child.parent is not self.ob: class_ = 'base' + class_ return class_ @page.renderer def lineno(self, request, tag): if not self.has_lineno_col: return () if hasattr(self.child, 'linenumber'): line = self.child.linenumber if self.child.sourceHref: line = tags.a(href=self.child.sourceHref)[line] return tag.clear()[line] else: return () @page.renderer def kind(self, request, tag): return tag.clear()[self.child.kind] @page.renderer def name(self, request, tag): return tag.clear()[util.taglink(self.child, self.child.name)] @page.renderer def summaryDoc(self, request, tag): return tag.clear()[self.docgetter.get(self.child, summary=True)]
class AttributeChild(page.Element): docFactory = loaders.xmlfile(util.templatefile('attribute-child.html')) def __init__(self, docgetter, ob): self.docgetter = docgetter self.ob = ob @page.renderer def functionAnchor(self, request, tag): return self.ob.fullName() @page.renderer def shortFunctionAnchor(self, request, tag): return self.ob.name @page.renderer def attribute(self, request, tag): return self.ob.name @page.renderer def functionBody(self, request, tag): return self.docgetter.get(self.ob)
class DiffPage(rend.Page): def __init__(self, root, ob, origob, editA, editB): self.root = root self.ob = ob self.origob = origob self.editA = editA self.editB = editB def render_title(self, context, data): return context.tag["Viewing differences between revisions ", self.editA.rev, " and ", self.editB.rev, " of ", u"\N{LEFT DOUBLE QUOTATION MARK}" + self.origob.fullName() + u"\N{RIGHT DOUBLE QUOTATION MARK}"] def render_diff(self, context, data): fd = FileDiff(self.ob.parentMod) fd.apply_edit(self.root.editsbyob[self.ob][0], self.editA) fd.reset() fd.apply_edit(self.editA, self.editB) return tags.pre[fd.diff()] docFactory = loaders.xmlfile(util.templatefile('diff.html'))
class BigDiffPage(rend.Page): def __init__(self, system, root): self.system = system self.root = root def render_bigDiff(self, context, data): mods = {} for m in self.root.editsbymod: l = [ e for e in self.root.editsbymod[m] if e is self.root.editsbyob[e.obj.doctarget][-1] ] l.sort(key=lambda x: x.obj.linenumber, reverse=True) mods[m] = FileDiff(m) for e in l: edit0 = self.root.editsbyob[e.obj][0] mods[m].apply_edit(edit0, e) r = [] for mod in sorted(mods, key=lambda x: x.filepath): r.append(tags.pre[mods[mod].diff()]) return r docFactory = loaders.xmlfile(util.templatefile('bigDiff.html'))
class IndexPage(page.Element): filename = 'index.html' docFactory = loaders.xmlfile(templatefile('index.html')) def __init__(self, system): self.system = system @page.renderer def project_link(self, request, tag): if self.system.options.projecturl: return tags.a(href=self.system.options.projecturl)[ self.system.options.projectname] elif self.system.options.projectname: return self.system.options.projectname else: return self.system.guessedprojectname @page.renderer def project(self, request, tag): if self.system.options.projectname: return self.system.options.projectname else: return self.system.guessedprojectname @page.renderer def recentChanges(self, request, tag): return () @page.renderer def problemObjects(self, request, tag): return () @page.renderer def onlyIfOneRoot(self, request, tag): if len(self.system.rootobjects) != 1: return [] else: root, = self.system.rootobjects return tag.clear()["Start at ", taglink(root), ", the root ", root.kind.lower(), "."] @page.renderer def onlyIfMultipleRoots(self, request, tag): if len(self.system.rootobjects) == 1: return [] else: return tag @page.renderer def roots(self, request, tag): item = tag.patternGenerator("item") r = [] for o in self.system.rootobjects: r.append(fillSlots(item, root=taglink(o))) return tag[r] @page.renderer def rootkind(self, request, tag): rootkinds = {} for o in self.system.rootobjects: rootkinds[o.kind.lower() + 's'] = 1 return tag.clear()['/'.join(sorted(rootkinds))] @page.renderer def buildtime(self, request, tag): return self.system.buildtime.strftime("%Y-%m-%d %H:%M:%S")
class CommonPage(page.Element): docFactory = loaders.xmlfile(templatefile('common.html')) def __init__(self, ob, docgetter=None): self.ob = ob if docgetter is None: docgetter = DocGetter() self.docgetter = docgetter self.usesorttable = ob.system.options.htmlusesorttable self.usesplitlinks = ob.system.options.htmlusesplitlinks self.shortenlists = ob.system.options.htmlshortenlists def title(self): return self.ob.fullName() def mediumName(self, obj): fn = obj.fullName() if '.' not in fn: return fn path, name = fn.rsplit('.', 1) def process(part): return obj.system.abbrevmapping.get(part, part[0]) return '.'.join([process(p) for p in path.split('.')]) + '.' + name def heading(self): return tags.h1(class_=self.ob.css_class)[self.mediumName(self.ob), " : ", self.ob.kind.lower(), " documentation"] def part(self): tag = tags.invisible() if self.ob.parent: parent = self.ob.parent if isinstance(parent, model.Module) and parent.name == '__init__': parent = parent.parent parts = [] while parent.parent: parts.append(taglink(parent, parent.name)) parts.append('.') parent = parent.parent parts.append(taglink(parent, parent.name)) parts.reverse() return tag['Part of ', parts] else: return tag def project(self): if self.ob.system.options.projecturl: return tags.a(href=self.ob.system.options.projecturl)[ self.ob.system.options.projectname] elif self.ob.system.options.projectname: return self.ob.system.options.projectname else: return self.ob.system.guessedprojectname def source(self, tag): sourceHref = srclink(self.ob) if not sourceHref: return () return tag(href=sourceHref) def inhierarchy(self, tag): return () def extras(self): return tags.invisible() def docstring(self): return self.docgetter.get(self.ob) def children(self): return sorted([o for o in self.ob.orderedcontents if o.isVisible], key=lambda o: -o.privacyClass) def packageInitTable(self): return () def baseTables(self, tag): return () def bigTable(self, tag): return () def mainTable(self): children = self.children() if children: return ChildTable(self.docgetter, self.ob, self.has_lineno_col(), children) else: return () def has_lineno_col(self): if not self.usesorttable: return False return isinstance(self.ob, (model.Class, model.Module)) def ifusesorttable(self, tag): if self.usesorttable: return tag else: return () def methods(self): return [ o for o in self.ob.orderedcontents if o.document_in_parent_page and o.isVisible ] def childlist(self): from pydoctor.nevowhtml.pages.attributechild import AttributeChild from pydoctor.nevowhtml.pages.functionchild import FunctionChild r = [] for c in self.methods(): if isinstance(c, model.Function): r.append( FunctionChild(self.docgetter, c, self.functionExtras(c))) else: r.append(AttributeChild(self.docgetter, c)) return r def functionExtras(self, data): return [] def functionBody(self, data): return self.docgetter.get(data) def ifhasplitlinks(self, tag): return () def pydoctorjs(self, tag): if self.usesplitlinks or self.shortenlists: return tag else: return () @page.renderer def all(self, request, tag): return fillSlots( tag, title=self.title(), ifusesorttable=self.ifusesorttable( tag.onePattern('ifusesorttable')), pydoctorjs=self.pydoctorjs(tag.onePattern('pydoctorjs')), heading=self.heading(), part=self.part(), source=self.source(tag.onePattern('source')), inhierarchy=self.inhierarchy(tag.onePattern('inhierarchy')), extras=self.extras(), docstring=self.docstring(), splittingLinks=self.ifhasplitlinks( tag.onePattern('splittingLinks')), mainTable=self.mainTable(), baseTables=self.baseTables(tag.patternGenerator('baseTable')), bigTable=self.bigTable(tag.patternGenerator('bigTable')), packageInitTable=self.packageInitTable(), childlist=self.childlist(), project=self.project(), buildtime=self.ob.system.buildtime.strftime("%Y-%m-%d %H:%M:%S"), )
class EditPage(rend.Page): def __init__(self, root, ob, docstring, isPreview, initialWhitespace): self.root = root self.ob = ob self.lines = open(self.ob.doctarget.parentMod.filepath, 'rU').readlines() self.docstring = docstring self.isPreview = isPreview self.initialWhitespace = initialWhitespace def render_title(self, context, data): return context.tag.clear()[ u"Editing docstring of \N{LEFT DOUBLE QUOTATION MARK}", self.ob.fullName(), u"\N{RIGHT DOUBLE QUOTATION MARK}"] def render_preview(self, context, data): docstring = parse_str(self.docstring) stan, errors = epydoc2stan.doc2html(self.ob, docstring=docstring) if self.isPreview or errors: if errors: tag = context.tag #print stan, errors #assert isinstance(stan, tags.pre) [text] = stan.children lines = text.replace('\r\n', '\n').split('\n') line2err = {} for err in errors: if isinstance(err, str): ln = None else: ln = err.linenum() line2err.setdefault(ln, []).append(err) w = len(str(len(lines))) for i, line in enumerate(lines): i += 1 cls = "preview" if i in line2err: cls += " error" tag[tags.pre(class_=cls)["%*s" % (w, i), ' ', line]] for err in line2err.get(i, []): tag[tags.p(class_="errormessage")[err.descr()]] i += 1 for err in line2err.get(i, []): tag[tags.p(class_="errormessage")[err.descr()]] items = [] for err in line2err.get(None, []): items.append(tags.li[str(err)]) if items: tag[tags.ul[items]] else: tag = context.tag[stan] return tag[tags.h2["Edit"]] else: return () def render_fullName(self, context, data): return self.ob.fullName() def render_initialWhitespace(self, context, data): return self.initialWhitespace def render_before(self, context, data): tob = self.ob.doctarget if tob.docstring: docstring_line_count = len(tob.docstring.orig.splitlines()) lineno = tob.docstring.linenumber - docstring_line_count else: lineno = tob.linenumber firstlineno = max(0, lineno - 6) lines = self.lines[firstlineno:lineno] if not lines: return () if firstlineno > 0: lines.insert(0, '...\n') return context.tag[lines] def render_divIndent(self, context, data): return 'margin-left: %dex;' % (indentationAmount(self.ob), ) def render_rows(self, context, data): return len(self.docstring.splitlines()) + 1 def render_textarea(self, context, data): return context.tag.clear()[self.docstring] def render_after(self, context, data): tob = self.ob.doctarget if tob.docstring: lineno = tob.docstring.linenumber else: lineno = tob.linenumber lastlineno = lineno + 6 lines = self.lines[lineno:lastlineno] if not lines: return () if lastlineno < len(self.lines): lines.append('...\n') return context.tag[lines] def render_url(self, context, data): return 'edit?ob=' + self.ob.fullName() docFactory = loaders.xmlfile(util.templatefile("edit.html"))