def html_from_mmm(mmm_attrs, add_header_func=None): """Returns valid XHTML page from given attributes.""" def anchor(str): return str.replace(' ', '_') def header_link(anchor): """Returns header permalink string for given anchor.""" return '<a href="#%s" class="headerlink" ' \ 'title="Permalink to this headline">¶</a>' % anchor def parse_section_outline(doc, section, section_name, is_index_page=False): doc.push_tag('ul') # <ul> doc.push_tag('li') # <li> doc.insert_link(section_name, '#' + anchor(section_name)) doc.push_tag('ul') # <ul> for subsection_name in section: if subsection_name == 'description': continue for subsubsection_name in section[subsection_name]: doc.push_tag('li') # <li> doc.insert_link(subsubsection_name, subsubsection_name + '.html' if is_index_page else '#' + anchor(subsubsection_name)) doc.pop_tag() # </li> doc.pop_tag() # </ul> doc.pop_tag() # </li> doc.pop_tag() # </ul> def parse_section_contents(doc, module_name, section, section_name, is_index_page=False): # <h2 id="section_name"> ... </h2> section_id = anchor(section_name) doc.insert_tag('h2', [('id', section_id)], text=section_name.title() + header_link(section_id)) doc.push_tag('dl', [('class', 'section')]) # <dl> if section.has_key('description'): doc.push_tag('dd') # <dd> doc.insert_paragraphs(section['description']) doc.pop_tag() # </dd> if is_index_page and section.has_key('modules'): parse_module_list(doc, section['modules']) if section.has_key('functions'): parse_functions_contents(doc, module_name, section['functions']) if section.has_key('constants'): parse_constants_contents(doc, module_name, section['constants']) doc.pop_tag() # </dl> def parse_functions_contents(doc, module_name, functions): def html_for_function(module_name, function, arguments): """Returns string of HTML for given function and attributes.""" args = ", ".join(['<span class="funcarg">%s</span>' % arg for arg in arguments]) class_tag = '<tt class="class-name">%s.</tt>' % module_name \ if module_name else '' return class_tag + \ '<tt class="name">%s</tt><big>(</big>%s<big>)</big>%s' \ % (function, args, header_link(anchor(function))) def parse_exceptions(doc, exceptions): doc.insert_tag('div', [('class', 'exceptions-header')], text='Exceptions:') doc.push_tag('ul', [('class', 'exceptions')]) # <ul> for exception_name in exceptions: text = "%s is thrown if %s." % \ (('<tt class="var">%s</tt>') % exception_name, exceptions[exception_name]) doc.insert_tag('li', text=text) # <li> ... </li> doc.pop_tag() # </ul> class_name = module_name for function_name in functions: function = functions[function_name] # <dt> ... </dt> class_name = module_name if not function.has_key('class') or \ function['class'] \ else '' doc.insert_tag('dt', [('class', 'function'), ('id', anchor(function_name))], text=html_for_function(class_name, function_name, function.get('args', []))) if function.has_key('description'): doc.push_tag('dd') # <dd> doc.insert_paragraphs(function['description']) if function.has_key('exceptions'): parse_exceptions(doc, function['exceptions']) doc.pop_tag() # </dd> def parse_constants_contents(doc, module_name, constants): def html_for_constant(module_name, name): class_tag = '<tt class="class-name">%s.</tt>' % module_name \ if module_name else '' name_id = anchor(name) return class_tag + \ '<tt class="name">%s</tt>%s' % (name, header_link(name_id)) for constant_name in constants: constant = constants[constant_name] # <dt> ... </dt> doc.insert_tag('dt', [('class', 'constant'), ('id', anchor(constant_name))], text=html_for_constant(module_name, constant_name)) if constant.has_key('description'): doc.push_tag('dd', [('class', 'constant')]) # <dd> doc.insert_paragraphs(constant['description']) doc.pop_tag() # </dd> def parse_module_list(doc, modules): def html_for_module(name, link): return '<a class="module" id="%s" href="%s">%s module</a>' % \ (anchor(name), link, name) for module_name in modules: # <dt> ... </dt> doc.insert_tag('dt', text=html_for_module(module_name, module_name + '.html')) doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n' \ '"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">' doc = XMLGen(doctype) doc.push_tag('html', [('xmlns', 'http://www.w3.org/1999/xhtml'), ('xml:lang', 'en')]) # <html> doc.push_tag('head') # <head> doc.insert_tag('meta', [('http-equiv', 'content-type'), ('content', 'text/html; charset=utf-8')], autoclose=True) # <meta content-type="..." /> summary = mmm_attrs.get('summary', '') if summary: doc.insert_tag('meta', [('name', 'description'), ('content', summary)], autoclose=True) # <meta name="description" /> title = '%s — %s' % (mmm_attrs['name'], summary) doc.insert_tag('title', text=title) # <title> ... </title> # Add stylesheet doc.insert_tag('link', [('rel', 'stylesheet'), ('href', 'style.css'), ('type', 'text/css'), ('charset', 'utf-8')], autoclose=True) # <link type="text/css" ... /> doc.pop_tag() # </head> doc.push_tag('body') # <body> if add_header_func: add_header_func(doc) doc.push_tag('div', [('id', 'container')]) # <div id="container"> doc.push_tag('div', [('id', 'sidebar')]) # <div id="sidebar"> doc.insert_tag('h3', text='Table of Contents') # <h3> ... </h3> doc.push_tag('ul') # <ul> # <li><a href="#module-name">module-name</a></li> title_anchor = anchor("module-%s" % mmm_attrs['name']) doc.push_tag('li') # <li> doc.insert_link(title, '#' + title_anchor) sections = mmm_attrs.get('sections', {}) is_index = mmm_attrs['type'] == 'index' for section_name in sections: parse_section_outline(doc, sections[section_name], section_name, is_index_page=is_index) doc.pop_tag() # </li> doc.pop_tag() # </ul> doc.pop_tag() # </div> doc.push_tag('div', [('id', 'main')]) # <div id="main"> doc.insert_tag('h1', [('id', title_anchor)], text=title + header_link(title_anchor)) # <h1> ... </h1> if mmm_attrs.has_key('description'): doc.push_tag('div', [('class', 'description')]) doc.insert_paragraphs(mmm_attrs['description']) doc.pop_tag() module_name = mmm_attrs['name'] if mmm_attrs['type'] == 'module' else '' for section_name in sections: parse_section_contents(doc, module_name, sections[section_name], section_name, is_index_page=is_index) doc.pop_tag() # </div> doc.pop_tag() # </div> doc.pop_tag() # </body> doc.pop_tag() # </html> document, errors = tidy_document(doc.str) return document
def create_mmm_file(name, module): """ Returns string describing an "MMM" psuedo-XML file using a module attributes dictionary. """ def insert_function_section(xml, function): xml.push_tag('function', [('name', function['name'])]) # <function> xml.insert_tag('syntax', text=function['syntax']) for tagname in ['description']: if function.has_key(tagname): xml.insert_tag(tagname, text=function[tagname]) if function.has_key('exceptions'): xml.push_tag('exceptions') # <exceptions> exceptions = function['exceptions'] for exception_name in exceptions: xml.insert_tag('exception', [('name', exception_name)], text=exceptions[exception_name]) xml.pop_tag() # </exceptions> xml.pop_tag() # </function> xml = XMLGen('<?xml version="1.0" encoding="UTF-8"?>') xml.push_tag('mmm', [('type', 'class' if 'class' in name else 'module')]) # <mmm> xml.insert_tag('name', text=name) # <name> ... </name> for tagname in 'summary', 'description': if module.has_key(tagname): xml.insert_tag(tagname, text=module[tagname]) if module.has_key('functions'): xml.push_tag('section', [('name', 'Functions')]) # <section> for function in module['functions']: insert_function_section(xml, function) xml.pop_tag() # </section> xml.pop_tag() # </mmm> return xml.str
def html_from_mmm(mmm_attrs, add_header_func=None, add_footer_func=None): """Returns valid XHTML page from given attributes.""" def anchor(str): return str.replace(' ', '_') def header_link(anchor): """Returns header permalink string for given anchor.""" return '<a href="#%s" class="headerlink" ' \ 'title="Permalink to this headline">¶</a>' % anchor def parse_section_outline(doc, section, section_name, is_index_page=False): doc.push_tag('ul') # <ul> doc.push_tag('li') # <li> doc.insert_link(section_name, '#' + anchor(section_name)) doc.push_tag('ul') # <ul> for subsection_name in section: if subsection_name == 'description': continue for subsubsection_name in section[subsection_name]: doc.push_tag('li') # <li> doc.insert_link(subsubsection_name, subsubsection_name + '.html' if is_index_page else '#' + anchor(subsubsection_name)) doc.pop_tag() # </li> doc.pop_tag() # </ul> doc.pop_tag() # </li> doc.pop_tag() # </ul> def parse_section_contents(doc, module_name, section, section_name, is_index_page=False): # <h2 id="section_name"> ... </h2> section_id = anchor(section_name) doc.insert_tag('h2', [('id', section_id)], text=section_name.title() + header_link(section_id)) doc.push_tag('dl', [('class', 'section')]) # <dl> if section.has_key('description'): doc.push_tag('dd') # <dd> doc.insert_paragraphs(section['description']) doc.pop_tag() # </dd> if is_index_page and section.has_key('modules'): parse_module_list(doc, section['modules']) if section.has_key('functions'): parse_functions_contents(doc, module_name, section['functions']) if section.has_key('constants'): parse_constants_contents(doc, module_name, section['constants']) doc.pop_tag() # </dl> def parse_functions_contents(doc, module_name, functions): def html_for_function(module_name, function, arguments): """Returns string of HTML for given function and attributes.""" args = ", ".join(['<span class="funcarg">%s</span>' % arg for arg in arguments]) class_tag = '<tt class="class-name">%s.</tt>' % module_name \ if module_name else '' return class_tag + \ '<tt class="name">%s</tt><big>(</big>%s<big>)</big>%s' \ % (function, args, header_link(anchor(function))) def parse_exceptions(doc, exceptions): doc.insert_tag('div', [('class', 'exceptions-header')], text='Exceptions:') doc.push_tag('ul', [('class', 'exceptions')]) # <ul> for exception_name in exceptions: text = "%s is thrown if %s." % \ (('<tt class="var">%s</tt>') % exception_name, exceptions[exception_name]) doc.insert_tag('li', text=text) # <li> ... </li> doc.pop_tag() # </ul> class_name = module_name for function_name in functions: function = functions[function_name] # <dt> ... </dt> class_name = module_name if not function.has_key('class') or \ function['class'] \ else '' doc.insert_tag('dt', [('class', 'function'), ('id', anchor(function_name))], text=html_for_function(class_name, function_name, function.get('args', []))) if function.has_key('description'): doc.push_tag('dd') # <dd> doc.insert_paragraphs(function['description']) if function.has_key('exceptions'): parse_exceptions(doc, function['exceptions']) doc.pop_tag() # </dd> def parse_constants_contents(doc, module_name, constants): def html_for_constant(module_name, name): class_tag = '<tt class="class-name">%s.</tt>' % module_name \ if module_name else '' name_id = anchor(name) return class_tag + \ '<tt class="name">%s</tt>%s' % (name, header_link(name_id)) for constant_name in constants: constant = constants[constant_name] # <dt> ... </dt> doc.insert_tag('dt', [('class', 'constant'), ('id', anchor(constant_name))], text=html_for_constant(module_name, constant_name)) if constant.has_key('description'): doc.push_tag('dd', [('class', 'constant')]) # <dd> doc.insert_paragraphs(constant['description']) doc.pop_tag() # </dd> def parse_module_list(doc, modules): def html_for_module(name, link): return '<a class="module" id="%s" href="%s">%s module</a>' % \ (anchor(name), link, name) for module_name in modules: # <dt> ... </dt> doc.insert_tag('dt', text=html_for_module(module_name, module_name + '.html')) doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n' \ '"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">' doc = XMLGen(doctype) doc.push_tag('html', [('xmlns', 'http://www.w3.org/1999/xhtml'), ('xml:lang', 'en')]) # <html> doc.push_tag('head') # <head> doc.insert_tag('meta', [('http-equiv', 'content-type'), ('content', 'text/html; charsetutf-8')], autoclose=True) # <meta content-type="..." /> summary = mmm_attrs.get('summary', '') if summary: doc.insert_tag('meta', [('name', 'description'), ('content', summary)], autoclose=True) # <meta name="description" /> title = '%s — %s' % (mmm_attrs['name'], summary) doc.insert_tag('title', text=title) # <title> ... </title> # Add stylesheet doc.insert_tag('link', [('rel', 'stylesheet'), ('href', 'style.css'), ('type', 'text/css'), ('charset', 'utf-8')], autoclose=True) # <link type="text/css" ... /> doc.pop_tag() # </head> doc.push_tag('body') # <body> if add_header_func: add_header_func(doc) doc.push_tag('div', [('id', 'container')]) # <div id="container"> doc.push_tag('div', [('id', 'sidebar')]) # <div id="sidebar"> doc.insert_tag('h3', text='Table of Contents') # <h3> ... </h3> doc.push_tag('ul') # <ul> # <li><a href="#module-name">module-name</a></li> title_anchor = anchor("module-%s" % mmm_attrs['name']) doc.push_tag('li') # <li> doc.insert_link(title, '#' + title_anchor) sections = mmm_attrs.get('sections', {}) is_index = mmm_attrs['type'] == 'index' for section_name in sections: parse_section_outline(doc, sections[section_name], section_name, is_index_page=is_index) doc.pop_tag() # </li> doc.pop_tag() # </ul> doc.pop_tag() # </div> doc.push_tag('div', [('id', 'main')]) # <div id="main"> doc.insert_tag('h1', [('id', title_anchor)], text=title + header_link(title_anchor)) # <h1> ... </h1> if mmm_attrs.has_key('description'): doc.push_tag('div', [('class', 'description')]) doc.insert_paragraphs(mmm_attrs['description']) doc.pop_tag() module_name = mmm_attrs['name'] if mmm_attrs['type'] == 'module' else '' for section_name in sections: parse_section_contents(doc, module_name, sections[section_name], section_name, is_index_page=is_index) doc.pop_tag() # </div> doc.pop_tag() # </div> if add_footer_func: add_footer_func(doc) doc.pop_tag() # </body> doc.pop_tag() # </html> document, errors = tidy_document(doc.str, {'char-encoding': 'utf8'}) return document