Exemplo n.º 1
0
    def test_parse_html1(self):
        parser = QqParser(
            allowed_tags={
                'chapter', 'section', 'subsection', 'subsubsection', 'eq',
                'eqref', 'ref', 'equation', 'label', 'idx'
            })
        doc = r"""\chapter
    Hello
    \label
        h1:label
\section
    World
"""
        tree = parser.parse(doc)
        html = QqHTMLFormatter(tree)
        s = html.do_format()
        print(s)
        soup = BeautifulSoup(s, 'html.parser')

        #self.assertEqual(s, """<h1 id="label_h1_label"><span class="section__number"><a href="#label_h1_label" class="section__number">1</a></span>Hello
        #</h1><h2 id="label_h2_number_1_1"><span class="section__number"><a href="#label_h2_number_1_1" class="section__number">1.1</a></span>World
        #</h2>""")

        self.assertEqual('label_h1_label', soup.h1['id'])
        self.assertEqual(['section__number'], soup.span['class'])
        self.assertEqual('#label_h1_label', soup.a['href'])
        self.assertEqual(['section__number'], soup.a['class'])
        self.assertEqual('1Hello', soup.h1.text.strip())
        self.assertEqual('1.1World', soup.h2.text.strip())
Exemplo n.º 2
0
    def test_parse_html2(self):
        parser = QqParser(
            allowed_tags={
                'chapter', 'section', 'subsection', 'subsubsection', 'eq',
                'eqref', 'ref', 'equation', 'label', 'idx'
            })
        doc = r"""\chapter \label h1:label
    Hello

This is a \ref{h1:label}.
"""
        tree = parser.parse(doc)
        html = QqHTMLFormatter(tree)
        s = html.do_format()
        soup = BeautifulSoup(s, 'html.parser')

        self.assertEqual(soup.h1['id'], 'label_h1_label')
        self.assertEqual(soup.span['class'], ['section__number'])
        self.assertEqual(soup.span.string, "1")
        self.assertEqual(
            soup("a")[1].attrs, {
                'class': ['a-ref'],
                'title': '',
                'href': '#label_h1_label'
            })
        self.assertEqual(soup("a")[1].string, "1")
Exemplo n.º 3
0
    def test_parse_html_math_align(self):

        html = QqHTMLFormatter()
        parser = QqParser(allowed_tags=html.uses_tags())

        doc = r"""\align
    \item c^2 &= a^2 + b^2 \label eq:one
    \item c &= \sqrt{a^2 + b^2} \label eq:two


See \ref{eq:one} and \ref{eq:two}
"""
        tree = parser.parse(doc)
        html.root = tree
        html.counters['equation'].showparents = False
        s = html.do_format()
        soup = BeautifulSoup(s, 'html.parser')
        print(repr(soup.text))
        self.assertEqual(
            soup.text,
            "\\[\n\\begin{align}\n\nc^2 &= a^2 + b^2 \n\\tag{1}\n\\\\\n"
            "c &= \\sqrt{a^2 + b^2} \n\\tag{2}\n\\\\\n\\end{align}\n\\]\n\n\n\nSee (1) and (2)"
        )
        self.assertEqual(soup.a['href'], "#mjx-eqn-1")
        self.assertEqual(soup.a.string, "(1)")
        self.assertEqual(soup("a")[1]['href'], "#mjx-eqn-2")
        self.assertEqual(soup("a")[1].string, "(2)")
Exemplo n.º 4
0
    def test_extract_toc(self):
        doc = dedent(r"""
        \section haha
        \chapter Chap-One
        Hello
        \section Sec-One
        World
        \section Sec-Two
        This
        \subsection SubSec-One
        Lala
        \subsection SubSec-Two
        Qqq
        \section Sec-Three
        Dada
        \chapter Chap-Two
        \subsection Strange
        \section Last
        """)
        parser = QqParser()
        formatter = QqHTMLFormatter()
        parser.allowed_tags.update(formatter.uses_tags())
        tree = parser.parse(doc)
        formatter.root = tree

        toc = formatter.extract_toc(maxlevel=3)
        self.assertEqual(
            toc.as_tuple(),
            (None, [(None, [('section', [])]),
                    ('chapter', [('section', []),
                                 ('section', [('subsection', []),
                                              ('subsection', [])]),
                                 ('section', [])]),
                    ('chapter', [(None, [('subsection', [])]),
                                 ('section', [])])]))
Exemplo n.º 5
0
def parse_and_format(doc: str,
                     formatter_factory,
                     allowed_tags = None) -> str:
    formatter = formatter_factory()
    if allowed_tags is None:
        allowed_tags = formatter.uses_tags()

    parser = QqParser(allowed_tags=allowed_tags)

    tree = parser.parse(doc)
    formatter.root = tree

    return formatter.do_format()
Exemplo n.º 6
0
def prepare_book():
    global wholebook
    if app.config.get("freeze"):
        global tree
        global formatter
        if wholebook is not None:
            return tree, formatter

    path = os.path.join(curdir, app.config["FILE"])
    if not os.path.isfile(path):
        abort(404)
    with open(path) as f:
        lines = f.readlines()
    parser = QqParser()
    formatter = QqFlaskHTMLFormatter(
        eq_preview_by_labels=not app.config.get("MATHJAX_WHOLEBOOK"))

    parser.allowed_tags.update(formatter.uses_tags())
    parser.allowed_tags.add("idx")  # for indexes
    tree = parser.parse(lines).process_include_tags(parser, curdir)
    formatter.root = tree
    formatter.pythonfigure_globals.update({"ob": odebook, "np": numpy})
    formatter.code_prefixes["pythonfigure"] += (
        "import numpy as np\n"
        "import qqmbr.odebook as ob\n"
        "# see https://github.com/ischurov/qqmbr/blob/master/qqmbr/odebook.py"
        "\n\n")

    formatter.code_prefixes["pythonvideo"] = formatter.code_prefixes[
        "pythonfigure"]

    formatter.plotly_globals.update({"np": numpy})
    formatter.code_prefixes["plotly"] = (
        formatter.code_prefixes.get("plotly", "") + "import numpy as np\n\n")

    formatter.mode = "bychapters"
    formatter.make_numbers(tree)
    formatter.make_chapters()

    # dirty hack to get equation snippet work

    if wholebook is None:
        if app.config.get("MATHJAX_WHOLEBOOK"):
            style, wholebook = mathjax(
                get_preamble(tree) + formatter.format(tree))
        else:
            wholebook = formatter.format(tree)
            style = ""
        app.config["css_correction"] = style + app.config.get("css_correction")

    return tree, formatter
Exemplo n.º 7
0
    def test_ref_with_separator(self):
        doc = r"""\chapter Hello \label sec:first

See \ref[section][sec:first] for details.
"""
        parser = QqParser()
        formatter = QqHTMLFormatter()
        parser.allowed_tags.update(formatter.uses_tags())
        tree = parser.parse(doc)
        formatter.root = tree
        html = formatter.do_format()
        soup = BeautifulSoup(html, "html.parser")
        self.assertEqual(soup("a")[1]['href'], "#label_sec_first")
        self.assertEqual(soup("a")[1].string, "section 1")
Exemplo n.º 8
0
    def test_refs_with_separator(self):
        doc = r"""\chapter Hello \label sec:first

\chapter World \label sec:other

See
\ref[section][sec:first] and \ref[section][sec:other] for details.
"""
        parser = QqParser()
        formatter = QqHTMLFormatter()
        parser.allowed_tags.update(formatter.uses_tags())
        tree = parser.parse(doc)
        formatter.root = tree
        print(tree.as_list())
        html = formatter.do_format()
        soup = BeautifulSoup(html, "html.parser")
        self.assertEqual(soup("a")[2].contents[0], "section 1")
Exemplo n.º 9
0
def render():
    text = request.values.get('text', '').replace('\r\n', '\n')
    formatter = QqHTMLFormatter()

    formatter.localnames = {}

    parser = QqParser(allowed_tags=formatter.safe_tags)
    try:
        tree = parser.parse(text)
    except Exception as e:
        return jsonify(error='parse error: ' + str(e))

    formatter.root = tree
    try:
        output = formatter.do_format()
    except Exception as e:
        return jsonify(error='format error: ' + str(e))
    return jsonify(output=output)
Exemplo n.º 10
0
def show_snippet(label):
    tree, formatter = prepare_book()
    tag = formatter.label_to_tag.get(label)

    if tag is None or tag.name != 'snippet':
        abort(404)
    if tag.exists("backref"):
        backref = tag.backref_.value
    else:
        backref = label

    parser = QqParser()
    parser.allowed_tags.update(formatter.uses_tags())
    backref_tag = parser.parse(r"\ref[Подробнее\nonumber][{}]".format(backref))
    tag.append_child(backref_tag.ref_)

    html = formatter.format(tag, blanks_to_pars=True)

    return mathjax_if_needed(html)[1]
Exemplo n.º 11
0
def convert(**args):
    path = os.path.join(curdir, app.config["FILE"])
    with open(path) as f:
        lines = f.readlines()

    formatter = QqHTMLFormatter()
    parser = QqParser(allowed_tags=formatter.uses_tags())

    try:
        tree = parser.parse(lines)
    except Exception as e:
        print("Parse error:", str(e))
        raise

    formatter.root = tree
    try:
        output = formatter.do_format()
    except Exception as e:
        print("Formatting error:", str(e))
        raise
    print(output)
Exemplo n.º 12
0
    def test_parse_html3(self):
        parser = QqParser(
            allowed_tags={
                'h1', 'h2', 'h3', 'h4', 'eq', 'eqref', 'ref', 'equation',
                'label', 'idx'
            })
        doc = r"""\equation \label eq:x2y2
    x^2 + y^2 = z^2

See \ref{eq:x2y2}.
"""
        tree = parser.parse(doc)
        html = QqHTMLFormatter(tree)
        html.counters['equation'].showparents = False
        s = html.do_format()
        soup = BeautifulSoup(s, 'html.parser')
        self.assertEqual(soup.div.attrs, {
            'id': "label_eq_x2y2",
            'class': ["latex_equation"]
        })
        self.assertEqual(soup.span['class'], ['ref'])
        self.assertEqual(soup.a['class'], ['a-ref'])
        self.assertEqual(soup.a['href'], '#mjx-eqn-1')
        self.assertEqual(soup.a.string, "(1)")
Exemplo n.º 13
0
    def test_tag2chapter(self):
        html = QqHTMLFormatter()
        parser = QqParser(allowed_tags=html.uses_tags())
        parser.allowed_tags.add('author')
        doc = r"""\author Ilya V. Schurov
\chapter Chapter 1
This is the first chapter
\equation \label eq1
    x^2 + y^2

\chapter Chapter 2
This is the second chapter
\section Section 1
Hello
\remark \label rem
    This is the end. \ref{eq1}
"""
        tree = parser.parse(doc)
        html.root = tree
        self.assertEqual(html.tag2chapter(tree.author_), 0)
        self.assertEqual(html.tag2chapter(tree.equation_), 1)
        self.assertEqual(html.tag2chapter(tree.equation_.label_), 1)
        self.assertEqual(html.tag2chapter(tree.remark_), 2)
        self.assertEqual(html.tag2chapter(tree.remark_.ref_), 2)
Exemplo n.º 14
0
def render(path):
    print(path_to_source_url(path))
    r = requests.get(path_to_source_url(path))
    r.encoding = 'UTF-8'
    if not r:
        abort(500)

    formatter = QqHTMLFormatter(with_chapters=False)

    formatter.localnames = {}

    parser = QqParser(allowed_tags=formatter.safe_tags)
    try:
        tree = parser.parse(r.text)
    except Exception as e:
        if app.debug:
            raise e
        return render_template("error.html",
                               error='parse error: ' + str(e)), 400

    formatter.root = tree
    try:
        output = formatter.do_format()
    except Exception as e:
        if app.debug:
            raise e
        return render_template("error.html",
                               error='format error: ' + str(e)), 400

    meta = tree.find_or_empty("meta")
    print(meta.as_list())

    return render_template("render_url.html",
                           output=output,
                           source_url=path_to_url(path),
                           meta=meta)