Beispiel #1
0
    def run(self, parent, blocks):
        block = blocks.pop(0)

        # Recover text
        match = self.re_example.match(block)
        input_lines = match.captures(1)
        output_lines = match.captures(2)

        input_text = '\n'.join(input_lines)
        output_text = '\n'.join(output_lines)

        # Create subtree
        main_block = etree.SubElement(parent, 'div')
        in_block_col = etree.SubElement(main_block, 'div')
        in_block = etree.SubElement(in_block_col, 'pre')
        out_block_col = etree.SubElement(main_block, 'div')
        out_block = etree.SubElement(out_block_col, 'pre')

        main_block.set('class', 'example row')
        in_block_col.set('class', 'col-md-6')
        in_block.set('class', 'input')
        out_block_col.set('class', 'col-md-6')
        out_block.set('class', 'output')

        in_block.text = AtomicString(input_text)
        out_block.text = AtomicString(output_text)
Beispiel #2
0
 def handle_match(m):
     node = etree.Element('script')
     node.set('type', 'math/tex; mode=display')
     if '\\begin' in m.group(2):
         node.text = AtomicString(m.group(2) + m.group(4) + m.group(5))
     else:
         node.text = AtomicString(m.group(3))
     return node
Beispiel #3
0
    def build_alert(self, classname, message):
        """
        Because an alert can have links in it, this is exponentially more
        complicated than it seems like it should be. Normally we can just
        build the alert and call it a day, but if there are any links in
        the message then we have to intelligently build the formatting
        for each link and place them into the message in the right places.

        This was a pain in the butt to get working and I hope it never breaks.
        """
        alert = Element("div")
        alert.set("class", f"alert alert-{classname} text-center")

        # ripped wholesale from the markdown package because it uses re instead
        # of regex, and regex can't use re-compiled regex
        STX = '\u0002'  # Use STX ("Start of text") for start-of-placeholder
        ETX = '\u0003'  # Use ETX ("End of text") for end-of-placeholder
        INLINE_PLACEHOLDER_PREFIX = STX + "klzzwxh:"
        INLINE_PLACEHOLDER = INLINE_PLACEHOLDER_PREFIX + "%s" + ETX
        INLINE_PLACEHOLDER_RE = regex.compile(INLINE_PLACEHOLDER % r'([0-9]+)')

        link_matches = [
            i for i in regex.finditer(INLINE_PLACEHOLDER_RE, message)
        ]
        if len(link_matches) == 0:
            alert.text = AtomicString(message)
            return alert

        # start with up to the beginning of the first link
        alert.text = AtomicString(message[:link_matches[0].start()])
        # python markdown stashes away things that it can't process immediately.
        # The problem comes when we try to modify strings that have stashed
        # nodes in them, which for some reason completely breaks Markdown's
        # ability to recall / reinstate those stashed nodes. That means
        # that we have to do the whole damn process ourselves.
        # tl;dr: perform a lot of string slicing to insert links in the right
        # spots so that everything works.
        stash = self.md.treeprocessors['inline'].stashed_nodes
        prev = None
        for link in link_matches:
            if prev:
                prev[0].tail = AtomicString(
                    message[prev[1].end():link.start()])
            mylink = stash[link.group(1)]
            link_alert = SubElement(alert, "a")
            link_alert.set("href", mylink.get('href'))
            link_alert.set('class', 'alert-link')
            link_alert.set("target", "_blank")

            link_alert.text = AtomicString(mylink.text)
            # group them together so we can use them on the next
            # iteration if we have more than one link
            prev = (link_alert, link)

        # Now that we're done with the loop, link_alert should be the last link
        # that was created.
        link_alert.tail = AtomicString(message[link.end():])
        return alert
Beispiel #4
0
 def handle_match(m):
     node = etree.Element("script")
     node.set("type", "math/tex; mode=display")
     if "\\begin" in m.group(2):
         node.text = AtomicString("".join(m.group(2, 4, 5)))
         return _wrap_node(node, "".join(m.group(1, 2, 4, 5, 6)), "div")
     else:
         node.text = AtomicString(m.group(3))
         return _wrap_node(node, "".join(m.group(2, 3, 4)), "div")
Beispiel #5
0
 def handle_match(m):
     node = etree.Element('script')
     node.set('type', 'math/tex; mode=display')
     if '\\begin' in m.group(2):
         node.text = AtomicString(''.join(m.group(2, 4, 5)))
         return _wrap_node(node, ''.join(m.group(1, 2, 4, 5, 6)), 'div')
     else:
         node.text = AtomicString(m.group(3))
         return _wrap_node(node, ''.join(m.group(2, 3, 4)), 'div')
Beispiel #6
0
 def handleMatch(self, m, data):
     node = Element('script')
     node.set('type', '%s; mode=display' % self._content_type)
     if '\\begin' in m.group(1):
         node.text = AtomicString(m.group(0))
     else:
         node.text = AtomicString(m.group(2))
     if self._add_preview:
         node = _wrap_node(node, m.group(0), 'div')
     return node, m.start(0), m.end(0)
Beispiel #7
0
 def handleMatch(self, m):
     ret = etree.Element('img')
     ret.set('src', AtomicString(m['src']))
     ret.set('alt', AtomicString(m['alt']))
     if m['title']:
         ret.set('title', AtomicString(m['title']))
     if m['width']:
         ret.set('width', m['width'])
     if m['height']:
         ret.set('height', m['height'])
     return ret
Beispiel #8
0
 def handleMatch(self, m):
     if m.group(4):
         text = m.group(4).strip()
         el = etree.Element('code')
         if text.startswith('#!'):
             el.text = AtomicString(text[2:].strip())
         else:
             el.attrib["class"] = "language-cpp"
             el.text = AtomicString(text.strip())
         return el
     else:
         return super(CppBacktickPattern, self).handleMatch(m)
 def append_newline_inside(self, el):
     # is it non-empty?
     if el:
         if el[-1].tail is None:
             el[-1].tail = AtomicString('\n')
         elif isinstance(el[-1].tail, AtomicString):
             el[-1].tail = AtomicString(el[-1].tail + '\n')
         else:
             el[-1].tail += '\n'
     # does it have text?
     elif el.text:
         el.text += '\n'
     # absolutely nothing, do nothing
     return el
Beispiel #10
0
 def handleMatch(self, m):
     node = etree.Element(None)
     text = ''
     for group in self.groups:
         text += m.group(group)
     node.text = AtomicString(text)
     return node;
Beispiel #11
0
 def handleMatch(self, match: Match) -> Element:
     groups = match.groupdict()
     element: Element = markdown.util.etree.Element('span')
     element.set('class', 'counter')
     element.set('title', 'counter')
     element.text = AtomicString(groups.get('numbers'))
     return element
Beispiel #12
0
 def handleMatch(self, m):
     el = etree.Element('a')
     entries = [self.parseEntry(e.strip()) for e in m.group(2).split(";")]
     el.text = AtomicString(m.group(2))
     el.set('class', 'serif-citation-block')
     el.set('data-items', json.dumps(entries))
     return el
Beispiel #13
0
    def handleMatch(self, m):
        gist_id = m.group('gist_id')
        gist_file = m.group('filename')

        gist_elem = etree.Element('div')
        gist_elem.set('class', 'gist')
        script_elem = etree.SubElement(gist_elem, 'script')

        if gist_file:
            script_elem.set('src', GIST_FILE_JS_URL.format(gist_id, gist_file))

        else:
            script_elem.set('src', GIST_JS_URL.format(gist_id))

        if requests:
            if gist_file:
                raw_gist = (self.get_raw_gist_with_filename(
                    gist_id, gist_file))
                script_elem.set('src',
                                GIST_FILE_JS_URL.format(gist_id, gist_file))

            else:
                raw_gist = (self.get_raw_gist(gist_id))
                script_elem.set('src', GIST_JS_URL.format(gist_id))

            # Insert source as <pre/> within <noscript>
            noscript_elem = etree.SubElement(gist_elem, 'noscript')
            pre_elem = etree.SubElement(noscript_elem, 'pre')
            pre_elem.text = AtomicString(raw_gist)

        else:
            warnings.warn('"requests" package not installed.  '
                          'Please install to add inline gist source.')

        return gist_elem
Beispiel #14
0
    def handleMatch(self, match):
        """
        process settings associated with !buildstatus markdown
        """
        reverse_margin = {'left': 'right', 'right': 'left', 'None': 'none'}

        url = match.group(2)

        # A tuple separating specific MOOSE documentation features (self._settings) from HTML styles
        settings = self.getSettings(match.group(3))

        # Create parent div, and set any allowed CSS
        parent_div = self.applyElementSettings(etree.Element('div'), settings)
        parent_div.set('class', 'moose-buildstatus')

        child_div = etree.SubElement(parent_div, 'div')
        jquery_script = etree.SubElement(parent_div, 'script')
        build_status_script = etree.SubElement(parent_div, 'script')

        jquery_script.set('src', 'http://code.jquery.com/jquery-1.11.0.min.js')

        # We need to inform SmartyPants to not format for paragraph use
        build_status_script.text = AtomicString(
            '$(document).ready(function(){ $("#buildstatus").load("%s");});' %
            (url))

        # Set some necessary defaults for our child div
        child_div.set('id', 'buildstatus')

        # Set any additional allowed CSS
        return parent_div
 def handleMatch(self, m, data):
     el = etree.Element(INDEXED_WORDS_TAG)
     el.set('class', INDEXED_WORDS_CLASSNAME)
     el.set('data-book-index', self.unescape(
         m.group(1).strip()))  # Use unescape to remove placeholders
     el.text = AtomicString(m.group(1).strip())
     return el, m.start(0), m.end(0)
    def run(self, parent, blocks):
        sibling = self.lastChild(parent)
        block = blocks.pop(0)

        block, theRest = self.detab(block)
        block = block.rstrip()

        block_is_html = False
        if "<div " in block or "</" in block or "<span " in block:
            block_is_html = True

        if (sibling is not None and sibling.tag == "div"):
            # The previous block was a code block. As blank lines do not start
            # new code blocks, append this block to the previous, adding back
            # linebreaks removed from the split into a list.

            block_is_html = block_is_html and not isinstance(sibling.text, AtomicString)

            block = u'\n'.join([sibling.text, block])
            output = sibling
        else:
            # This is a new codeblock. Create the elements and insert text.
            output = markdown.util.etree.SubElement(parent, 'div', {'class': 'code-output'})

        # If not HTML, add the `pre` class so that we know to render output as raw text
        if not block_is_html and 'pre' not in output.get('class', 'code-output'):
            output.set('class', ' '.join([output.get('class', ''), 'pre']))

        output.text = "{}\n".format(block) if block_is_html else AtomicString("{}\n".format(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)
Beispiel #17
0
 def handleMatch(self, match: Match) -> Element:
     groups = match.groupdict()
     element: Element = markdown.util.etree.Element('i')
     element.set('lang', 'pi')
     element.set('translate', 'no')
     element.text = AtomicString(groups.get('text'))
     return element
Beispiel #18
0
    def handleMatch(self, m):
        gist_id = m.group('gist_id')
        gist_file = m.group('filename')

        gist_elem = etree.Element('div')
        gist_elem.set('class', 'gist')
        script_elem = etree.SubElement(gist_elem, 'script')

        noscript_elem = etree.SubElement(gist_elem, 'noscript')

        try:
            if gist_file:
                script_elem.set('src',
                                GIST_FILE_JS_URL.format(gist_id, gist_file))
                raw_gist = (self.get_raw_gist_with_filename(
                    gist_id, gist_file))

            else:
                script_elem.set('src', GIST_JS_URL.format(gist_id))
                raw_gist = (self.get_raw_gist(gist_id))

            # Insert source as <pre/> within <noscript>
            pre_elem = etree.SubElement(noscript_elem, 'pre')
            pre_elem.text = AtomicString(raw_gist)

        except GistFetchException as e:
            LOGGER.warn(e.message)
            warning_comment = etree.Comment(' WARNING: {0} '.format(e.message))
            noscript_elem.append(warning_comment)

        return gist_elem
def safe_concat(a, b):
    ''' to deal with cases when a is None '''
    if isinstance(a, AtomicString):
        return AtomicString(a + b)
    else:
        # otherwise a is str-like or none
        return (a or '') + b
Beispiel #20
0
def prettify_diff(parent, diff_in):
    for line in iter(diff_in):
        if len(line) >= 4 and line[0:4] == "+++ ":
            file_container = etree.SubElement(parent, "div")
            file_container.set("class", "file_container")
            filename_container = etree.SubElement(file_container, "div")
            filename = line.split()[1]
            filename_container.text = "/".join(filename.split("/")[2:])
            filename_container.set('class', 'filename')
        elif len(line) >= 4 and line[0:4] == "--- ":
            pass
        elif len(line) >= 3 and line[0:3] == '@@ ':
            start_line = re.match('@@ -(\d+)(,\d+)? \+\d+(,\d+)? @@',
                                  line).group(1)
            hunk_header = etree.SubElement(file_container, "div")
            hunk_header.text = "line %s..." % start_line
            hunk_header.set('class', 'hunk_header')
            hunk_container = etree.SubElement(file_container, "pre")
            hunk_container.set("class", "diff")
            hunk_code = etree.SubElement(hunk_container, "code")
            hunk_code.text = ''
        else:
            c = {
                '-': 'diff_old',
                '+': 'diff_new',
                ' ': 'diff_unchanged'
            }.get(line[0])
            newelement = etree.SubElement(hunk_code, "div")
            newelement.set("class", c)
            newelement.text = AtomicString(line[1:])
Beispiel #21
0
 def handleMatch(self, m, data):
     node = Element('script')
     node.set('type', self._content_type)
     node.text = AtomicString(m.group(2))
     if self._add_preview:
         node = _wrap_node(node, m.group(0), 'span')
     return node, m.start(0), m.end(0)
Beispiel #22
0
    def append(text, sibling):
        preElement = sibling.find("*/pre")

        currentCode = preElement.text
        lines = [x for x in currentCode.split('\n') if x]
        lines.append(text)

        preElement.text = AtomicString('%s' % ('\n'.join(lines)))
Beispiel #23
0
 def handleMatch(self, m):
     el = etree.Element("a")
     href = m.group(2)
     if not re.match('^(ftp|https?)://', href, flags=re.IGNORECASE):
         href = 'http://%s' % href
     el.set('href', self.unescape(href))
     el.text = AtomicString(m.group(2))
     return el
Beispiel #24
0
 def _wrap_node(node, preview_text, wrapper_tag):
     if not self.getConfig("add_preview"):
         return node
     preview = etree.Element("span", {"class": "MathJax_Preview"})
     preview.text = AtomicString(preview_text)
     wrapper = etree.Element(wrapper_tag)
     wrapper.extend([preview, node])
     return wrapper
Beispiel #25
0
 def _wrap_node(node, preview_text, wrapper_tag):
     if not self.getConfig('add_preview'):
         return node
     preview = etree.Element('span', {'class': 'MathJax_Preview'})
     preview.text = AtomicString(preview_text)
     wrapper = etree.Element(wrapper_tag)
     wrapper.extend([preview, node])
     return wrapper
Beispiel #26
0
    def handleMatch(self, m):
        subsc = m.group(3)

        text = subsc

        el = etree.Element('sub')
        el.text = AtomicString(text)
        return el
Beispiel #27
0
    def make_link(self, category, obj, url, text):
        """Make an <a> element

        Override this to set custom attributes, e.g. title.
        """
        el = etree.Element('a')
        el.set('href', url)
        el.text = AtomicString(text)
        return el
Beispiel #28
0
 def handleMatch(self, m):
     el = etree.Element('span')
     el.set('class', 'type')
     types = m.group(3)
      # Make sure types are shown as type1 | type2
     types = re.sub(' or ', ' | ', types)
     types = re.sub(r'(?<=\w)[|](?=\w)', ' | ', types)
     el.text = AtomicString(types)
     return el
Beispiel #29
0
 def handleMatch(self, m, data):
     for value, is_block in zip(m.groups(), (False, True, True)):
         if value:
             break
     script = etree.Element('script', type='math/tex' + ('; mode=display' if is_block else ''))
     preview = etree.Element('span', {'class': 'MathJax_Preview'})
     preview.text = script.text = AtomicString(value)
     wrapper = etree.Element('span')
     wrapper.extend([preview, script])
     return wrapper, m.start(0), m.end(0)
    def run(self, parent, blocks):
        block = blocks.pop(0)
        m = re.fullmatch(self.RE_DISPLAY_BLOCK, block, re.DOTALL)

        e = etree.SubElement(parent, 'script')
        e.set('type', 'math/tex; mode=display')
        e.text = AtomicString(self.ELEM_TEXT_BEGIN + m.group(1).strip('\n') +
                              self.ELEM_TEXT_END)

        return True