Beispiel #1
0
 def test_parse_fragment_fail(self):
     """if given broken document parse_fragment() raises RuntimeError and
     prints errors"""
     with captured_output() as out:
         with self.assertRaises(RuntimeError):
             parse_fragment(r"\begin{fooenv}bla", "en")
         err_out = out[1].getvalue()
     self.assertTrue("ERROR" in err_out)
Beispiel #2
0
    def test_parse_fragment(self):
        """parse_fragment() returns valid output if given test document"""
        doc = parse_fragment(CONTENT, "en")
        h_1 = doc[0]
        para_1 = doc[1]
        h_2 = doc[2]
        para_2 = doc[3]

        # test types
        type_tests = (
            (h_1, pf.Header),
            (h_1, pf.Header),
            (h_1.content[0], pf.Str),
            (h_1.content[1], pf.Space),
            (h_1.content[2], pf.Str),
            (para_1, pf.Para),
            (h_2, pf.Header),
            (para_1, pf.Para),
        )
        for elem in type_tests:
            with self.subTest(_type=type(elem[0])):
                self.assertIsInstance(elem[0], elem[1])

        # test content
        content_tests = (
            (h_1.content[0].text, "Test"),
            (h_1.content[2].text, "heading"),
            (len(para_1.content), 121),
            (h_2.content[0].text, "Another"),
            (h_2.content[2].text, "heading"),
            (len(para_2.content), 149),
        )
        for elem in content_tests:
            with self.subTest(value=elem[0]):
                self.assertEqual(elem[0], elem[1])
Beispiel #3
0
def create_header(
    title_str, doc, level=0, parse_text=False, identifier="", short_title=None
):
    """
    Create a header element.

    Because headers need to be referenced by later elements, references to the
    last found header is remembered.
    """
    if not isinstance(doc, pf.Doc):
        raise ValueError("create_header without Doc element")

    attributes = {}
    if short_title == title_str:
        short_title = None
    if short_title is not None:
        # Attach short title as attribute to be picked up later on by generate_innodoc
        attributes["short_title"] = short_title

    if parse_text:
        title = parse_fragment(title_str, doc.metadata["lang"].text)[0].content
    else:
        title = destringify(title_str)
    header = pf.Header(
        *title, level=level, identifier=identifier, attributes=attributes
    )
    remember(doc, "label", header)
    return header
Beispiel #4
0
def create_content_box(elem_content, elem_classes, lang):
    """
    Create a content box.

    Convenience function for creating content boxes that only differ
    by having diffent content and classes.
    """
    if not elem_classes or elem_classes == []:
        msg = "create_content_box without element classes: {}".format(elem_classes)
        raise ValueError(msg)

    if not elem_content or elem_content == "":
        msg = "create_content_box without element content: {}".format(elem_content)
        raise ValueError(msg)

    div = pf.Div(classes=elem_classes)
    content = parse_fragment(elem_content, lang)

    # Check if environment had an \MLabel/SiteUXID identifier
    identifier = extract_identifier(content)
    if identifier:
        div.identifier = identifier

    div.content.extend(content)
    return div
Beispiel #5
0
 def handle_input(self, cmd_args, elem):
     r"""Handle ``\input`` command."""
     filepath = join(getcwd(), cmd_args[0])
     with open(filepath, "r") as input_file:
         input_content = input_file.read()
     environ["INNOCONV_MINTMOD_CURRENT_DIR"] = dirname(filepath)
     return parse_fragment(input_content, elem.doc.metadata["lang"].text)
Beispiel #6
0
 def _replace_mexerciseitems(self, elem):
     r"""Helper function to replace `MExerciseItems` with enumerate in elem
     text and return the pandoc output of the parsed altered element."""
     elem.text = elem.text.replace("\\begin{MExerciseItems}",
                                   "\\begin{enumerate}")
     elem.text = elem.text.replace("\\end{MExerciseItems}",
                                   "\\end{enumerate}")
     return parse_fragment(elem.text, elem.doc.metadata["lang"].text)
Beispiel #7
0
 def handle_minputhint(self, cmd_args, elem):
     r"""Handle ``\MInputHint`` command."""
     content = parse_fragment(cmd_args[0], elem.doc.metadata["lang"].text)
     if isinstance(elem, pf.Block):
         div = pf.Div(classes=ELEMENT_CLASSES["MINPUTHINT"])
         div.content.extend(content)
         return div
     span = pf.Span(classes=ELEMENT_CLASSES["MINPUTHINT"])
     if content and isinstance(content[0], pf.Para):
         span.content.extend(content[0].content)
     return span
Beispiel #8
0
    def handle_mdirectrouletteexercises(self, cmd_args, elem):
        r"""Handle ``\MDirectRouletteExercises`` command.

        Remember points for next question.
        """
        filepath = join(environ["INNOCONV_MINTMOD_CURRENT_DIR"], cmd_args[0])
        with open(filepath, "r") as input_file:
            input_content = input_file.read()
        content = parse_fragment(input_content, elem.doc.metadata["lang"].text)
        div = pf.Div(classes=ELEMENT_CLASSES["MDIRECTROULETTEEXERCISES"])
        div.content.extend(content)
        return div
Beispiel #9
0
    def handle_highlight(self, cmd_args, elem):
        r"""Handle \highlight command.

        This seems to be some sort of formatting command. There's no
        documentation and it does nothing in the mintmod code. We just keep
        the information here.
        """
        return pf.Span(
            *parse_fragment(cmd_args[0],
                            elem.doc.metadata["lang"].text)[0].content,
            classes=ELEMENT_CLASSES["HIGHLIGHT"],
        )
Beispiel #10
0
    def handle_mequationitem(self, cmd_args, elem):
        r"""Handle ``\MEquationItem`` command."""

        if len(cmd_args) != 2:
            raise ValueError(
                r"\MEquationItem needs 2 arguments. Received: {}".format(
                    cmd_args))

        content_left = parse_fragment(cmd_args[0],
                                      elem.doc.metadata["lang"].text)
        content_right = parse_fragment(cmd_args[1],
                                       elem.doc.metadata["lang"].text)

        content = to_inline([
            content_left,
            pf.Math(r"\;\;=\;", format="InlineMath"), content_right
        ])

        if isinstance(elem, pf.Block):
            return pf.Plain(content)

        return content
Beispiel #11
0
 def handle_mexercises(self, elem_content, env_args, elem):
     r"""Handle ``\MExercises`` environment."""
     content = parse_fragment(elem_content, elem.doc.metadata["lang"].text)
     lang = elem.doc.metadata["lang"].text
     header = create_header(TRANSLATIONS["exercises"][lang],
                            elem.doc,
                            level=3)
     identifier = extract_identifier(content)
     if identifier:
         header.identifier = identifier
     # pylint: disable=no-member
     header.classes.extend(ELEMENT_CLASSES["MEXERCISES"])
     content.insert(0, header)
     return content
Beispiel #12
0
 def handle_mcontent(self, elem_content, env_args, elem):
     r"""Handle ``\MContent`` environment."""
     content = parse_fragment(elem_content, elem.doc.metadata["lang"].text)
     lang = elem.doc.metadata["lang"].text
     header = create_header(
         TRANSLATIONS["content"][lang],
         elem.doc,
         level=3,
         identifier="content",
     )
     identifier = extract_identifier(content)
     if identifier:
         header.identifier = identifier
     content.insert(0, header)
     return content
Beispiel #13
0
    def handle_mxcontent(self, elem_content, env_args, elem):
        r"""Handle ``\MXContent`` environment."""
        content = parse_fragment(elem_content, elem.doc.metadata["lang"].text)

        # special case: Skip header creation for some weird (meta?) caption in
        # entrance test.
        if env_args[0] != "Restart" and env_args[0] != "Neustart":
            header = create_header(env_args[0],
                                   elem.doc,
                                   level=3,
                                   short_title=env_args[1])
            identifier = extract_identifier(content)
            if identifier:
                header.identifier = identifier
            content.insert(0, header)

        return content
Beispiel #14
0
 def handle_mintro(self, elem_content, env_args, elem):
     r"""Handle ``\MIntro`` environment."""
     content = parse_fragment(elem_content, elem.doc.metadata["lang"].text)
     lang = elem.doc.metadata["lang"].text
     header = create_header(
         TRANSLATIONS["introduction"][lang],
         elem.doc,
         level=3,
         identifier="introduction",
     )
     identifier = extract_identifier(content)
     if identifier:
         header.identifier = identifier
     # pylint: disable=no-member
     header.classes.extend(ELEMENT_CLASSES["MINTRO"])
     content.insert(0, header)
     return content
Beispiel #15
0
    def handle_mentry(self, cmd_args, elem):
        r"""Handle ``\MEntry`` command.

        This command creates an entry for the index.
        """

        if isinstance(elem, pf.Block):
            log("Warning: Expected Inline for MEntry: {}".format(cmd_args))

        text = cmd_args[0]
        concept = cmd_args[1]
        for repl in MATH_SUBSTITUTIONS:  # can contain LaTeX!
            concept = re.sub(repl[0], repl[1], concept)
        strong = pf.Strong()
        strong.content.extend(
            parse_fragment(text, elem.doc.metadata["lang"].text)[0].content)
        span = pf.Span()
        span.attributes = {INDEX_ATTRIBUTE: concept}
        span.content = [strong]
        return block_wrap(span, elem)
Beispiel #16
0
def create_image(filename, descr, elem, add_descr=True, block=True):
    """Create an image element."""

    img = pf.Image(url=filename, classes=ELEMENT_CLASSES["IMAGE"])

    if add_descr:
        descr = parse_fragment(descr, elem.doc.metadata["lang"].text, as_doc=True)
        img.title = shorten(
            pf.stringify(*descr.content).strip(), width=125, placeholder="..."
        )
    else:
        img.title = descr

    if block:
        ret = pf.Div(pf.Plain(img), classes=ELEMENT_CLASSES["FIGURE"])
        remember(elem.doc, "label", ret)
        if add_descr:
            ret.content.append(descr.content[0])
    else:
        remember(elem.doc, "label", img)
        ret = img

    return ret
Beispiel #17
0
    def handle_mtest(self, elem_content, env_args, elem):
        r"""Handle ``\MTest`` environment."""
        content = parse_fragment(elem_content, elem.doc.metadata["lang"].text)
        title = env_args[0]

        # Normalize various forms of inconsistent titles
        if "Abschlusstest" in title:  # Final test
            title = "Abschlusstest"
        elif "Final Test" in title:
            title = "Final Test"
        elif "Eingangstest" in title:  # Entrance test
            title = "Test 1: Abzugebender Teil"
        elif "Graded Test" in title:
            title = "Test 1: Graded Part To Be Submitted"

        header = create_header(title, elem.doc, level=2)
        identifier = extract_identifier(content)
        if identifier:
            header.identifier = identifier

        # pylint: disable=no-member
        header.classes.extend(ELEMENT_CLASSES["MTEST"])
        content.insert(0, header)
        return content
Beispiel #18
0
 def handle_msectionstart(self, elem_content, env_args, elem):
     r"""Handle ``\MSectionStart`` environment."""
     return parse_fragment(elem_content, elem.doc.metadata["lang"].text)
Beispiel #19
0
 def handle_modsemph(self, cmd_args, elem):
     r"""Handle \modsemph command."""
     return pf.Emph(*parse_fragment(
         cmd_args[0], elem.doc.metadata["lang"].text)[0].content)
Beispiel #20
0
 def handle_mexercisecollection(self, elem_content, env_args, elem):
     r"""Handle ``\MExerciseCollection`` environment."""
     return parse_fragment(elem_content, elem.doc.metadata["lang"].text)
Beispiel #21
0
 def test_parse_fragment_quiet(self):
     """parse_fragment() prints debug messages"""
     with captured_output() as out:
         parse_fragment(r"\section{foo} \unknownfoobar", "en")
         err_out = out[1].getvalue()
     self.assertTrue("Could not handle command unknownfoobar" in err_out)
Beispiel #22
0
    def handle_mquestiongroup(self, elem_content, env_args, elem):
        r"""Handle ``\MQuestionGroup`` environments.

        In mintmod used to group checkboxes together. We just return the
        content as questions are grouped by exercises anyway."""
        return parse_fragment(elem_content, elem.doc.metadata["lang"].text)
Beispiel #23
0
 def test_parse_fragment_not_in_path(self, mock_func):
     # pylint: disable=unused-argument
     """parse_fragment() raises OSError if panzer not in PATH"""
     with self.assertRaises(OSError):
         parse_fragment("foo bar", "en")
Beispiel #24
0
 def test_parse_fragment_empty(self):
     """parse_fragment() returns empty list if given empty document"""
     ret = parse_fragment("", "en")
     self.assertEqual(len(ret), 0)
Beispiel #25
0
 def test_parse_fragment_log_is_called(self, log_mock):
     """parse_fragment() calls log function on warning"""
     parse_fragment(r"\unknowncommandfoobar", "en")
     self.assertTrue(log_mock.called)
Beispiel #26
0
 def handle_html(self, elem_content, env_args, elem):
     r"""Handle ``\html`` environment."""
     return parse_fragment(elem_content,
                           elem.doc.metadata["lang"].text,
                           from_format="html")