def buildScript(self, parent, eq_id, tex): """ Create the KaTeX script element. """ script = etree.SubElement(parent, 'script') text = 'var element = document.getElementById("{}");'.format(eq_id) text += 'try{katex.render("%s", element, {displayMode:%s});}' % ( tex, self.DISPLAY_MODE) text += 'catch (exception){' text += 'console.log("KaTeX render failed: {}");'.format(tex) text += 'var err=document.createElement("span");' text += 'err.setAttribute("class", "moose-katex-error");' text += 'err.textContent = "LaTeX Error: {}";'.format(tex) text += 'element.appendChild(err);' text += '}' script.text = self.markdown.htmlStash.store(text)
def handleMatch(self, m): line = m.group(2) self._set_columns(line) # row column el1 = etree.Element("div") el1.set('class', 'instruction bg-info row') # create the columns. for idx, column in enumerate(self.cols): width, content = column _col = etree.SubElement(el1, "div") _col.set('class', 'col-sm-{} col{}'.format(width, idx)) _col.text = content return el1
def subsystemsElement(self, sys_name, settings): """ Create table of sub-systems. """ collection = MooseDocs.extensions.create_system_collection( sys_name, self._syntax) if collection: el = self.applyElementSettings(etree.Element('div'), settings) if settings['title']: h2 = etree.SubElement(el, 'h{}'.format(settings['title_level'])) h2.text = settings['title'] el.append(collection) else: el = etree.Element('p') return el
def run(self, parent, blocks): print '' print 'running' print '' sibling = self.lastChild(parent) block = blocks.pop(0) m = GUIDE_RE.search(block) print m if m: block = block[m.end() + 1:] # removes the first line div = etree.SubElement(parent, 'div') div.set('class', '%s' % "powpow") else: div = sibling self.parser.parseChunk(div, block)
def createCarousel(self, options, top_div, files): """ Creates the actual HTML required for the carousel to work. Input: options[dict]: Set on the slideshow line of the markdown top_div: div element that will be the carousel files[list]: List of dicts with filename paths and associated captions """ carousel_options = { "interval": options.get("interval", "5000"), "pause": options.get("pause", "hover"), "wrap": options.get("wrap", "true"), "keyboard": options.get("keyboard", "true"), } cid = "carousel%s" % self.MATCHES_FOUND top_div.set("id", cid) top_div.set("class", "carousel slide") top_div.set("data-ride", "carousel") top_div.set("data-interval", carousel_options["interval"]) top_div.set("data-pause", carousel_options["pause"]) top_div.set("data-wrap", carousel_options["wrap"]) top_div.set("data-keyboard", carousel_options["keyboard"]) ol = etree.SubElement(top_div, 'ol') ol.set("class", "carousel-indicators") default_caption = options.get("caption", "") for i in range(len(files)): li = etree.SubElement(ol, 'li') li.set("data-target", "#%s" % cid) if i == 0: li.set("class", "active") li.set("data-slide-to", str(i)) inner_div = etree.SubElement(top_div, 'div') inner_div.set("class", "carousel-inner") inner_div.set("role", "listbox") for i, f in enumerate(files): item_div = etree.SubElement(inner_div, "div") active = "" if i == 0: active = "active" item_div.set("class", "item %s" % active) img = etree.SubElement(item_div, "img") img.set("src", os.path.join('/media', os.path.basename(f["path"]))) caption = f["caption"] if not caption: caption = default_caption if caption: cap_div = etree.SubElement(item_div, "div") cap_div.set("class", "carousel-caption") cap_div.text = caption self.addControl(top_div, cid, "prev", "Previous") self.addControl(top_div, cid, "next", "Next") self.MATCHES_FOUND += 1 return top_div
def run(self, parent, blocks): block = blocks.pop(0) m = self.RE.search(block) before, block, theRest = self.extractBlock(m, block) if before: self.parser.parseBlocks(parent, [before]) div = etree.SubElement(parent, 'div') div.set('class', '%s' % (self.classType, )) self.parser.parseChunk(div, block) if theRest: blocks.insert(0, theRest)
def _create_video(self, m, vtype, width, height, url): vid = m.group('%s_vid' % vtype) url = url % vid url = url.replace('&', '&') div = etree.Element('div') div.set('class', 'video %s' % vtype) iframe = etree.SubElement(div, 'iframe') iframe.set('allowfullscreen', 'true') iframe.set('frameborder', '0') iframe.set('width', str(width)) iframe.set('height', str(height)) iframe.set('scrolling', 'no') iframe.set('src', url) return etree.tostring(div)
def handleMatch(self, m): id = m.group(2) if id in self.footnotes.footnotes.keys(): sup = etree.Element("sup") a = etree.SubElement(sup, "a") sup.set('id', self.footnotes.makeFootnoteRefId(id)) a.set('href', '#' + self.footnotes.makeFootnoteId(id)) a.set('rel', 'footnote') a.text = unicode(self.footnotes.footnotes.index(id) + 1) # Add the first 50 characters to the title attribute plus an ellipsis if necessary footnote_text = self.footnotes.footnotes[id] ellipsis = '...' if len(footnote_text) > 50 else '' a.set('title', footnote_text[:50] + ellipsis) return sup else: return None
def run(self, root): rss = etree.Element("rss") rss.set("version", "2.0") channel = etree.SubElement(rss, "channel") for tag, text in ( ("title", self.ext.getConfig("TITLE")), ("link", self.ext.getConfig("URL")), ("description", None), ): element = etree.SubElement(channel, tag) element.text = text for child in root: if child.tag in ["h1", "h2", "h3", "h4", "h5"]: heading = child.text.strip() item = etree.SubElement(channel, "item") link = etree.SubElement(item, "link") link.text = self.ext.getConfig("URL") title = etree.SubElement(item, "title") title.text = heading guid = "".join([x for x in heading if x.isalnum()]) guidElem = etree.SubElement(item, "guid") guidElem.text = guid guidElem.set("isPermaLink", "false") elif child.tag in ["p"]: try: description = etree.SubElement(item, "description") except UnboundLocalError: # Item not defined - moving on pass else: if len(child): content = "\n".join( [etree.tostring(node) for node in child]) else: content = child.text pholder = self.markdown.htmlStash.store("<![CDATA[ %s]]>" % content) description.text = pholder return rss
def run(self, parent, blocks): block = blocks.pop(0) # Replace relevant pipes to protect wikilinks block = self.RE_PIPE_SELECTION.sub(self.pipe_replacement, block) rows = block.split('\n') table = etree.SubElement(parent, 'table') table.set('class', 'ltag') tbody = etree.SubElement(table, 'tbody') max_col_number = 0 text_in_the_middle_td = None for row in rows: # Text in the middle case if self.is_line_ltag(row): text_in_the_middle_td = None if text_in_the_middle_td is not None: text_in_the_middle_td.text = text_in_the_middle_td.text \ + "<br/>" + row continue if self.is_line_ltag_for_text_in_the_middle(row): tr = etree.SubElement(tbody, 'tr') text_in_the_middle_td = etree.SubElement(tr, 'td') text_in_the_middle_td.set('colspan', str(max_col_number - 1)) text_in_the_middle_td.text \ = self.RE_LTAG_FOR_TEXT_IN_THE_MIDDLE.sub('', row) continue tr = etree.SubElement(tbody, 'tr') cols = row.split(self.pipe_replacement) col_number = 1 # Pitch / Relay cell td = etree.SubElement(tr, 'td') td.text = self.process_ltag(cols[0], col_number) col_number += 1 # Others cells for col in cols[1:]: td = etree.SubElement(tr, 'td') td.text = self.process_ltag(col, col_number) col_number += 1 max_col_number = max(col_number, max_col_number) self.increment_row_count(row)
def run(self, parent, blocks): """ Starts parsing the block of text which contains the table. It first finds the header (if one exists) as ended by a row of '=' characters. It then gets all the cells in the body (as a separate table from the header; this needs to be changed). If getting either the header or the body fails, the table is instead rendered as a block of text. Otherwise, it is rendered as a table with the appropriate row and column spans. """ block = blocks.pop(0) before = [] rows = [] after = [] Started = False InTable = True for r in block.split('\n'): if not Started: if (r.startswith('+') or r.startswith('|')): Started = True else: before.append(r) if Started and InTable and (r.startswith('+') or r.startswith('|')): rows.append(r.strip()) elif Started: InTable = False after.append(r) if len(before) > 0: self.parser.parseBlocks(parent, ["\n".join(before)]) try: orig_block = rows body_block = orig_block[:] success, body = self._get_all_cells(body_block) if not success: self._render_as_block(parent, '\n'.join(orig_block)) return table = etree.SubElement(parent, 'table') self._render_rows(body, table) if len(after) > 0: blocks.insert(0, "\n".join(after)) except: blocks.insert(0, block) return False
def run(self, parent: etree.Element, blocks: List[str]) -> None: sibling = self.lastChild(parent) block = blocks.pop(0) m = PLACEHOLDER_RE.search(block) if m: index = int(m.group(1)) block = getattr(self.md, 'bootstrap_stash')[index] try: tree = etree.fromstring(block) except etree.ParseError as e: pre = etree.SubElement(parent, 'pre') pre.text = f'{e}\n{escape(block)}' else: self._parse(parent, tree) elif sibling: self.parser.parseChunk(sibling, block)
def _replace_block(self, text): # Parse configuration params m = self.FENCED_BLOCK_RE.search(text) if not m: m = self.BLOCK_RE.search(text) if not m: return text, False # Parse configuration params img_format = m.group('format') if m.group( 'format') else self.config['format'] classes = m.group('classes') if m.group( 'classes') else self.config['classes'] alt = m.group('alt') if m.group('alt') else self.config['alt'] title = m.group('title') if m.group('title') else self.config['title'] # Extract diagram source end convert it code = m.group('code') diagram = self.generate_uml_image(code, img_format) if img_format == 'png': data = 'data:image/png;base64,{0}'.format( base64.b64encode(diagram).decode('ascii')) img = etree.Element('img') img.attrib['src'] = data img.attrib['classes'] = classes img.attrib['alt'] = alt img.attrib['title'] = title elif img_format == 'svg': # Firefox handles only base64 encoded SVGs data = 'data:image/svg+xml;base64,{0}'.format( base64.b64encode(diagram).decode('ascii')) img = etree.Element('img') img.attrib['src'] = data img.attrib['classes'] = classes img.attrib['alt'] = alt img.attrib['title'] = title elif img_format == 'txt': # logger.debug(diagram) img = etree.Element('pre') code = etree.SubElement(img, 'code') code.attrib['class'] = 'text' code.text = AtomicString(diagram.decode('UTF-8')) return text[:m.start()] + etree.tostring( img).decode() + text[m.end():], True
def handleMatch(self, match): """ Creates chart from a chart template. """ # Extract settings and template template = match.group('template') + '.js' settings = self.getSettings(match.group('settings'), legacy_style=False) # Create a float element div = self.createFloatElement(settings) # Create 'chart_id' for linking JS with <div> settings['chart_id'] = 'moose-google-{}-chart-{}'.format( self.TEMPLATE, int(self._count)) self._count += 1 # Paths to Google Chart template paths = [ os.path.join(MooseDocs.MOOSE_DIR, 'docs', 'templates', 'gchart'), os.path.join(os.getcwd(), 'templates', 'gchart') ] # Apply the arguments to the template self.clearStatus() env = jinja2.Environment(loader=jinja2.FileSystemLoader(paths)) self.globals(env) template = env.get_template(template) complete = template.render(**self.arguments(settings)) if self._status is not None: return self.createErrorElement(self._status, title="Google Chart Creation Error", error=False) # Create the <script> tag script = etree.SubElement(div, 'script') script.set('type', 'text/javascript') script.text = self.markdown.htmlStash.store(complete, safe=True) # Add the <div> to be replaced with the chart el = etree.Element('div') el.set('id', settings['chart_id']) div.insert(0, el) return div
def run(self, fname, optstr): opts = {} opts['spec'] = 'width-500' opts['classname'] = 'left' for opt in optstr: bits = opt.split('=', 1) opt = bits[0] value = '' if len(bits) > 1: value = bits[1] if opt == 'left': opts['classname'] = 'left' elif opt == 'right': opts['classname'] = 'right' elif opt == 'full': opts['classname'] = 'full-width' elif opt == 'width': try: opts['spec'] = "width-%d" % int(value) except ValueError: pass try: image = get_image_model().objects.get(title=fname) except ObjectDoesNotExist: return '[image "{}" not found]'.format(fname) except MultipleObjectsReturned: return '[multiple images "{}" found]'.format(fname) image_url = image.file.url rendition = image.get_rendition(opts['spec']) a = etree.Element('a') a.set('data-toggle', 'lightbox') a.set('data-type', 'image') a.set('href', image_url) img = etree.SubElement(a, 'img') img.set('src', rendition.url) img.set('class', opts['classname']) img.set('width', str(rendition.width)) img.set('height', str(rendition.height)) return a
def run(self, fname, optstr): opts = {} opts["spec"] = "width-500" opts["classname"] = "left" for opt in optstr: bits = opt.split("=", 1) opt = bits[0] value = "" if len(bits) > 1: value = bits[1] if opt == "left": opts["classname"] = "left" elif opt == "right": opts["classname"] = "right" elif opt == "full": opts["classname"] = "full-width" elif opt == "width": try: opts["spec"] = "width-%d" % int(value) except ValueError: pass try: image = get_image_model().objects.get(title=fname) except ObjectDoesNotExist: return '[image "{}" not found]'.format(fname) except MultipleObjectsReturned: return '[multiple images "{}" found]'.format(fname) image_url = image.file.url rendition = image.get_rendition(opts["spec"]) a = etree.Element("a") a.set("data-toggle", "lightbox") a.set("data-type", "image") a.set("href", image_url) img = etree.SubElement(a, "img") img.set("src", rendition.url) img.set("class", opts["classname"]) img.set("width", str(rendition.width)) img.set("height", str(rendition.height)) return a
def run(self, parent, blocks): """ Starts parsing the block of text which contains the table. It first finds the header (if one exists) as ended by a row of '=' characters. It then gets all the cells in the body (as a separate table from the header; this needs to be changed). If getting either the header or the body fails, the table is instead rendered as a block of text. Otherwise, it is rendered as a table with the appropriate row and column spans. """ orig_block = [r.strip() for r in blocks.pop(0).split('\n')] body_block = orig_block[:] success, body = self._get_all_cells(body_block) if not success: self._render_as_block(parent, '\n'.join(orig_block)) return table = etree.SubElement(parent, 'table') self._render_rows(body, table)
def run(self, parent, blocks): match = self.PATTERN.match(blocks.pop(0)) type = match.group('type') start = None end = None if type is not None: n = int(match.group('n')) if type == 'before': end = n elif type == 'after': start = n + 1 else: return scoreboard = etree.SubElement(parent, 'div', {'class': 'scoreboard'}) html = get_template('archives/inline-scoreboard.html').render( {'scoreboard': self.scoreboard[start:end]} ) scoreboard.append(etree.fromstring(html))
def run(self, parent, blocks): """ Generate dot svg and html for displaying the image. """ # Extract the block of interest block = blocks.pop(0) # Test if graphviz can be found executable = os.path.join(self._graphviz, 'dot') if not os.path.exists(executable): return self.createErrorElement(block, title='Failed to locate Graphviz', parent=parent) # Create the temporary dot file dot_file = 'tmp_' + uuid.uuid4().hex + '.dot' with open(dot_file, 'w') as fid: fid.write(block) # Create a temporary svg file out_file = "media/tmp_{}.moose.{}".format(uuid.uuid4().hex, self._ext) # Execute graphviz to generate the svg file try: cmd = [executable, '-T' + self._ext, dot_file, '-o', out_file] output = subprocess.check_output(cmd) log.debug('Created SVG chart using dot: {}'.format(out_file)) except: if os.path.exists(dot_file): os.remove(dot_file) return self.createErrorElement(block, title='Failed to execute Graphviz', parent=parent) # Clean up dot temporary if os.path.exists(dot_file): os.remove(dot_file) # Create the img that will contain the flow chart img = etree.SubElement(parent, "img") img.set('class', 'moose-diagram') img.set('src', '/' + out_file) img.set('style', 'background:transparent; border:0px')
def run(self, parent: etree.Element, blocks: List[str]) -> None: lines = blocks.pop(0).splitlines() m = re.search(r"(\d+)cols", lines[0]) if m: n_cols = int(m.group(1)) while 12 % n_cols: n_cols -= 1 col_class = "col-md-%d" % (12 / n_cols) else: col_class = "col-md-4" del lines[0] gallery = etree.SubElement(parent, 'div', {"class": "gallery"}) cointainer = etree.SubElement(gallery, 'div', {"class": "cointainer"}) elm_row = etree.SubElement( cointainer, 'div', { "class": "thumbnails row text-center justify-content-center", "data-toggle": "lightbox" }) for line in lines: m = self.INNER_RE.match(line) assert m title = m.group("text") original_url = m.group("image") if original_url.startswith(':'): original_url = original_url[1:] else: print( f'Warning: Gallery image url must start with ":": "{original_url}".' ) width, height = parse_size(m.group("params")) thumbnail = add_thumbnail(self.md, Thumbnail(original_url, width, height)) elm_column = etree.SubElement(elm_row, "div", {"class": col_class}) elm_a = etree.SubElement(elm_column, "a", { "title": title, "href": ":" + original_url, "class": "thumbnail" }) img_attr = { "src": ':' + thumbnail.filename, 'class': 'img-thumbnail img-fluid', 'alt': title, } if width: img_attr["width"] = str(width) if height: img_attr["height"] = str(height) etree.SubElement(elm_a, "img", img_attr)
def handleMatch(self, m, data): image, start, index = super().handleMatch(m, data) if image is None or not image.get("title"): return image, start, index src = image.get("src") caption = image.get("title") if src.startswith("http"): raise ValueError(f"Image path {src} has been given. Only images " "available on the file system can be added.") image_path = Path(src) if not image_path.is_absolute(): image_path = (self.base_path / image_path).resolve() url = WEBVIZ_ASSETS.add(image_path) image_style = "" for style_prop in image.get("alt").split(","): prop, value = style_prop.split("=") if prop == "width": image_style += f"width: {value};" elif prop == "height": image_style += f"height: {value};" if image_style: image.set("style", image_style) image.set("src", url) image.set("class", "_markdown_image") container = etree.Element("span") container.append(image) etree.SubElement(container, "span", attrib={ "class": "_markdown_image_caption" }).text = caption return container, start, index
def create_collection(name, syntax, action, groups=None, **kwargs): """ Creates subobject collection for a given node from the YAML dump. Inputs: name: The name of the object/system syntax: The dict of MooseApplicationSyntax objects action[str]: Function on the MooseApplicationSyntax object to call ('system' or 'object') groups[list]: The list of groups to restrict the collection. """ groups = groups if groups else syntax.keys() use_header = True if len(groups) > 1 else False children = [] for group in groups: if action == 'object': items = get_collection_items( syntax[group].objects(name, include_self=False), **kwargs) elif action == 'system': items = get_collection_items( syntax[group].actions(name, include_self=False), **kwargs) else: LOG.error('Invalid action name, must supply "system" or "object".') return None if items and use_header: li = etree.Element('li') header = etree.SubElement(li, 'div') header.set('class', 'collapsible-header moose-group-header') header.text = '{} {}'.format(syntax[group].name(), '{}s'.format(action.title())) items.insert(0, header) children += items collection = None if children: collection = etree.Element('ul') collection.set('class', 'collapsible') collection.set('data-collapsible', 'accordion') collection.extend(children) return collection
def build_toc_etree(self, div, toc_list): # Add title to the div if self.config["title"]: header = etree.SubElement(div, "span") header.attrib["class"] = "toctitle" header.text = self.config["title"] def build_etree_ul(toc_list, parent): ul = etree.SubElement(parent, "ul") for item in toc_list: # List item link, to be inserted into the toc div li = etree.SubElement(ul, "li") link = etree.SubElement(li, "a") link.text = item.get('name', '') link.attrib["href"] = '#' + item.get('id', '') if item['children']: build_etree_ul(item['children'], li) return ul return build_etree_ul(toc_list, div)
def render_members( self, elem: etree.Element, item: typing.Any, members: typing.List[str] = None ) -> None: members_elem = etree.SubElement(elem, "div") members_elem.set("class", "autodoc-members") if members is None: members = sorted([attr for attr in dir(item) if not attr.startswith("_")]) info_items = [] for attribute_name in members: attribute = getattr(item, attribute_name) docs = trim_docstring(getattr(attribute, "__doc__", "")) info = (attribute_name, docs) info_items.append(info) for attribute_name, docs in info_items: attribute = getattr(item, attribute_name) self.render_signature(members_elem, attribute, attribute_name) self.render_docstring(members_elem, attribute, docs)
def handleMatch(self, match): #pylint: disable=unused-argument """ Build the matrix. """ repo_issue = "https://github.com/idaholab/moose/issues" ol = etree.Element('ol') ol.set('class', 'collection browser-default') for req in get_requirements(): li = etree.SubElement(ol, 'li') li.set('class', 'collection-item') p = etree.SubElement(li, 'p') p.text = req.requirement p = etree.SubElement(li, 'p') p.text = 'Specification: ' a = etree.SubElement(p, 'a') a.set('href', '{}/{}'.format(self._repo, req.path)) a.text = '{}:{}'.format(req.path, req.name) if req.design: p = etree.SubElement(li, 'p') p.text = 'Design: ' for design in req.design.split(): node = self.getFilename(design) a = etree.SubElement(p, 'a') a.set("href", '/' + node[1].destination) a.text = node[1].name + ' ' if req.issues: p = etree.SubElement(li, 'p') p.text = 'Issues: ' for issue in req.issues.split(): a = etree.SubElement(p, 'a') a.set("href", "{}/{}".format(repo_issue, issue[1:])) a.text = issue + ' ' return ol
def run(self, parent, blocks): sibling = self.lastChild(parent) block = blocks.pop(0) m = RX.search(block) if m: block = block[m.end() + 1:] # removes the first line block, theRest = self.detab(block) if m: klass = m.group(1) div = etree.SubElement(parent, 'div') div.set('class', '%s %s' % (CLASSNAME, klass)) else: div = sibling self.parser.parseChunk(div, block) if theRest: # This block contained unindented line(s) after the first indented # line. Insert these lines as the first block of the master blocks # list for future processing. blocks.insert(0, theRest)
def run(self, parent, blocks): original_block = blocks[0] blocks[0] = re.sub(self.RE_FENCE_START, '', blocks[0]) # Find block with ending fence for block_num, block in enumerate(blocks): if re.search(self.RE_FENCE_END, block): # remove fence blocks[block_num] = re.sub(self.RE_FENCE_END, '', block) # render fenced area inside a new div e = etree.SubElement(parent, 'div') e.set('style', 'display: inline-block; border: 1px solid red;') self.parser.parseBlocks(e, blocks[0:block_num + 1]) # remove used blocks for i in range(0, block_num + 1): blocks.pop(0) return True # or could have had no return statement # No closing marker! Restore and do nothing blocks[0] = original_block return False # equivalent to our test() routine returning False
def render_signature(self, elem: etree.Element, item: typing.Any, import_string: str) -> None: module_string, _, name_string = import_string.rpartition('.') signature = inspect.signature(item) # Eg: `some_module.attribute_name` signature_elem = etree.SubElement(elem, 'p') signature_elem.set('class', 'autodoc-signature') if inspect.isclass(item): qualifier_elem = etree.SubElement(signature_elem, 'em') qualifier_elem.text = "class " if module_string: module_elem = etree.SubElement(signature_elem, 'code') module_elem.text = module_string + '.' module_elem.set('class', 'autodoc-module') name_elem = etree.SubElement(signature_elem, 'code') name_elem.text = name_string name_elem.set('class', 'autodoc-name') # Eg: `(a, b='default', **kwargs)`` bracket_elem = etree.SubElement(signature_elem, 'span') bracket_elem.text = '(' bracket_elem.set('class', 'autodoc-punctuation') for param, is_last in last_iter(get_params(signature)): param_elem = etree.SubElement(signature_elem, 'em') param_elem.text = param param_elem.set('class', 'autodoc-param') if not is_last: comma_elem = etree.SubElement(signature_elem, 'span') comma_elem.text = ', ' comma_elem.set('class', 'autodoc-punctuation') bracket_elem = etree.SubElement(signature_elem, 'span') bracket_elem.text = ')' bracket_elem.set('class', 'autodoc-punctuation')
def run(self, parent, blocks): raw_block = blocks.pop(0) match_start = self.RE_START.search(raw_block) if match_start: # Opening a new block. rest = raw_block[match_start.end():] if self._last_parent: # Inconsistent state (nested starting markers). Ignore the marker # and keep going. blocks.insert(0, rest) return div = etree.SubElement(parent, 'div') # Setting the class name is sufficient, because doc.css already has # styles for these classes. div.set('class', match_start.group(1)) self._last_parent = parent blocks.insert(0, rest) self.parser.parseBlocks(div, blocks) return match_end = self.RE_END.search(raw_block) if match_end: # Ending an existing block. # Process the text preceding the ending marker in the current context # (i.e. within the div block). rest = raw_block[:match_end.start()] self.parser.parseBlocks(parent, [rest]) if not self._last_parent: # Inconsistent state (the ending marker is found but there is no # matching starting marker). # Let's continue as if we did not see the ending marker. return last_parent = self._last_parent self._last_parent = None self.parser.parseBlocks(last_parent, blocks) return
def run(self, parent, blocks): lines = blocks.pop(0).split('\n') heading = self.pattern.match(lines[0]).groupdict() depth = min(6, int(len(heading.get('depth')))) id = heading.get('id').split(',') if len(id) == 2: cls = id[1] id = id[0] else: id = id[0] cls = 'section' h = etree.SubElement(parent, 'h{depth}'.format(depth=depth)) h.attrib['id'] = id h.attrib['class'] = cls h.text = heading.get('text') for i, line in enumerate(lines[1:]): blocks.insert(i, line)