Exemple #1
0
def make_codelisting(inner_elements, caption, label, *,
                     shortcaption=None, above=True):
    r"""Creates a source code listing:

        \begin{codelisting}[hbtp]
        inner_elements
        \caption[caption]{\label{label}caption}
        \end{codelisting}

    and returns the list containing the pandoc elements.

    Args:
        inner_elements: A list of inner pandoc elements, usually a
                        code block and potentially outputs etc.
        caption:        The caption to be used. Will be used below code and in
                        list of code listings.
        label:          The label to use.
        shortcaption:   A short caption to be used in the list of code listings.
                        If None, the normal caption will be used.
        above:          The caption is placed above (True) or below (False)
                        the code listing.

    Returns:
        A list of elements for this codelisting.
    """
    begin = pf.RawBlock(r'\begin{codelisting}[hbtp]', format='tex')
    end = pf.RawBlock(r'\end{codelisting}', format='tex')

    if not shortcaption:
        shortcaption = caption
    cap_begin = f'\\caption[{shortcaption}]{{\\label{{{label}}}'
    caption_elem = pf.RawBlock(cap_begin + caption + '}', format='tex')
    if above:
        return [begin, caption_elem] + inner_elements + [end]
    return [begin] + inner_elements + [caption_elem, end]
Exemple #2
0
def codeblock(elem, doc):
    if not isinstance(elem, pf.CodeBlock) or escape_char not in elem.text:
        return None

    is_raw = not elem.classes

    if is_raw:
        elem.classes.append('default')
        elem.attributes['style'] = 'color: inherit'

    datadir = doc.get_metadata('datadir')
    syntaxdir = os.path.join(datadir, 'syntax')

    text = pf.convert_text(elem,
                           input_format='panflute',
                           output_format=doc.format,
                           extra_args=[
                               '--syntax-definition',
                               os.path.join(syntaxdir, 'isocpp.xml')
                           ])

    def repl(match_obj):
        match = match_obj.group(1)
        if not match:  # @@
            return match_obj.group(0)
        if match.isspace():  # @  @
            return match
        return pf.convert_text(pf.Plain(*pf.convert_text(match)[0].content),
                               input_format='panflute',
                               output_format=doc.format)

    result = pf.RawBlock(escape_span.sub(repl, text), doc.format)

    return pf.Div(pf.RawBlock('{\\renewcommand{\\NormalTok}[1]{#1}', 'latex'),
                  result, pf.RawBlock('}', 'latex')) if is_raw else result
Exemple #3
0
def finalize(doc):
    """Function called at the end of the filter"""
    doc.metadata["compiletime"] = pf.MetaString(
        time.strftime("%m/%d/%Y %H:%M:%S"))
    if doc.format == "html":
        dumpyaml(doc.toc, "toc.yaml")
        writetoc(doc, tochtml(doc.toc, doc.get_metadata("booktitle", "")))
        if doc.get_metadata("indexpage", False):
            indexhtml(doc)
        file = doc.get_metadata("filename", "")
        title = doc.get_metadata("title", "")
        searchindex = doc.get_metadata("searchindex", "")
        logstring("Search index " + file + "," + title + "," + searchindex,
                  doc)
        if file and title and searchindex:
            t = re.sub(r"\\\w+", " ", doc.searchtext.lower())
            text = re.sub("[^a-zA-Z -]", "", t)
            updateindex(searchindex, file + ".html", title, text, doc)

    if doc.format == "html" and doc.footnotecontents:
        logstring("inserting " + str(doc.footnotecontents), doc)
        L = ([pf.RawBlock("<ol>", format="html")] + doc.footnotecontents +
             [pf.RawBlock("</ol>", format="html")])
        footnotes = pf.Div(*L, identifier="footnotediv", classes=["footnotes"])
        doc.content.append(footnotes)

    doc.logfile.close()
Exemple #4
0
def prepare(doc):
    date = doc.get_metadata('date')
    if date == 'today':
        doc.metadata['date'] = datetime.date.today().isoformat()

    doc.metadata['pagetitle'] = pf.convert_text(
        pf.Plain(*doc.metadata['title'].content),
        input_format='panflute',
        output_format='markdown')

    datadir = doc.get_metadata('datadir')

    with open(os.path.join(datadir, 'annex-f'), 'r') as f:
        stable_names.update(line.split() for line in f)

    def highlighting(output_format):
        return pf.convert_text(
            '`_`{.default}',
            output_format=output_format,
            extra_args=[
              '--highlight-style', os.path.join(datadir, 'syntax', 'wg21.theme'),
              '--template', os.path.join(datadir, 'template', 'highlighting')
            ])

    doc.metadata['highlighting-macros'] = pf.MetaBlocks(
        pf.RawBlock(highlighting('latex'), 'latex'))
    doc.metadata['highlighting-css'] = pf.MetaBlocks(
        pf.RawBlock(highlighting('html'), 'html'))
def table_separators(elem, doc):
    if isinstance(elem, pf.Table) and doc.enable_traditional_tables:
        if latex_format(doc.format):
            doc.metadata['tables'] = True
            raw_item = pf.convert_text(elem,
                                       input_format='panflute',
                                       output_format='latex')
            print("raw_item", file=sys.stderr)
            #pf.debug(hack_table(raw_item))
            return [pf.RawBlock(hack_table(raw_item), 'latex')]
        elif html_format(doc.format):
            raw_item = pf.convert_text(elem,
                                       input_format='panflute',
                                       output_format='html')
            raw_item = raw_item.replace(
                '<table>',
                '<table style=\'border-collapse: collapse; border: 1px solid black\'>'
            )
            raw_item = raw_item.replace(
                '<th ', '<th style=\'border: 1px solid black\' ')
            raw_item = raw_item.replace(
                '<td ',
                '<td style=\'border: 1px solid black; height: 20px;\' ')
            return [pf.RawBlock(raw_item, 'html')]
    return None
Exemple #6
0
def prepare(doc):
    datadir = doc.get_metadata('datadir')

    kate = pf.run_pandoc(args=['--print-highlight-style', 'kate'])
    json_styles = json.loads(kate)

    json_styles['background-color'] = '#' + doc.get_metadata('shadecolor')
    text_styles = json_styles['text-styles']
    text_styles['BuiltIn'] = text_styles['Normal']
    text_styles['Comment']['italic'] = True
    text_styles['ControlFlow'] = text_styles['DataType']
    text_styles['Keyword'] = text_styles['DataType']
    text_styles['Variable']['text-color'] = '#' + doc.get_metadata('addcolor')
    text_styles['String']['text-color'] = '#' + doc.get_metadata('rmcolor')

    with tempfile.NamedTemporaryFile('w', suffix='.theme') as f:
        json.dump(json_styles, f)
        f.flush()

        def highlighting(output_format):
            return pf.convert_text('`_`{.cpp}',
                                   output_format=output_format,
                                   extra_args=[
                                       '--highlight-style', f.name,
                                       '--template',
                                       os.path.join(datadir, 'template',
                                                    'highlighting')
                                   ])

        doc.metadata['highlighting-macros'] = pf.MetaBlocks(
            pf.RawBlock(highlighting('latex'), 'latex'))
        doc.metadata['highlighting-css'] = pf.MetaBlocks(
            pf.RawBlock(highlighting('html'), 'html'))
Exemple #7
0
def h_latex_div(e, doc):
    r"""make every div with class=foo to begin{foo} ... end{foo}
    if there is title then it is begin{foo}[title] instead
    if there is an identifier then we add \label[foo]{id}"""
    if not isinstance(e, pf.Div): return None
    if not len(e.classes): return None

    c = e.classes[0]
    title = e.attributes.get("title", "")
    label = labelref(e, doc)
    if label in doc.labels:
        name = getlabel(label, doc)[0]
    else:
        name = c.capitalize()
    if title: name += f" ({title}) "
    e.attributes["name"] = name

    if e.identifier:
        doc.label_descriptions[e.identifier] = c.capitalize()
    if doc.format == 'html' and c == 'quote':
        return pf.BlockQuote(e)
    if doc.format != 'latex': return None
    dref = e.attributes.get("data-ref", None)
    if not title and c == "proof" and dref and dref != doc.lastlabel:
        title = fr"Proof of \cref{{{dref}}}"
    label = labelref(e, doc)
    doc.lastlabel = label
    before = rf"\begin{{{c}}}[{title}]" if title else rf"\begin{{{c}}}"
    if label: before += rf" \label[{c}]{{{label}}}"
    if c == "algorithm": before += r"~ \\ \noindent" + "\n"
    after = rf"\end{{{c}}}"
    _before = pf.RawBlock(before, format='latex')
    _after = pf.RawBlock(after, format='latex')
    e.content = [_before] + list(e.content) + [_after]
    return e
Exemple #8
0
def h_pseudocode(e, doc):
    if not isinstance(e, pf.CodeBlock) or not "algorithm" in e.classes:
        return None
    content = e.text
    if e.identifier:
        doc.label_descriptions[e.identifier] = "Algorithm"
    label = labelref(e, doc)
    _, number_, _ = get_full_label(label, doc)
    if number_ and number_ != "??":
        i = number_.rfind(".")
        number = int(number_[i + 1:]) if i > -1 else int(number_)
    else:
        number = 0
    title = e.attributes.get("title", "")
    if doc.format == "latex":
        textitle = f"[{title}]" if title else ""
        result = (dedent(rf"""
        \begin{{algorithm}}{textitle}
        \label[algorithm]{{{label}}} ~ \\ \noindent
        \begin{{algorithmic}}[1]
        """) + "\n" + format_pseudocode(content) + dedent(fr"""
        \end{{algorithmic}}
        \end{{algorithm}}
        """))
        return pf.RawBlock(result, format="latex")
    if doc.format == "html":
        textitle = f"\caption{{{title}}}" if title else ""
        uid = str(uuid.uuid4())
        content = (format_pseudocode(content).replace(
            "\\INPUT", "\\REQUIRE").replace("\\OUTPUT", "\\ENSURE"))
        result = (dedent(rf"""
            <pre id="{uid}" class="pseudocodetext" style="display:none;">
            \begin{{algorithm}}
            {textitle}
            \begin{{algorithmic}}
            """) + "\n" + content + dedent(fr"""
            \end{{algorithmic}}
            \end{{algorithm}}
            </pre>
            <div id="{uid}result" class="pseudocodeoutput" ></div>

            <script>
            document.addEventListener('readystatechange', event => {{
            if (event.target.readyState === "complete") {{
                var code = document.getElementById('{uid}').textContent;
                var resultEl = document.getElementById('{uid}result');
                resultEl.innerHTML = '';
                var options = {{
                    captionCount: {number-1},
                    lineNumber: true
                }};
                pseudocode.render(code, resultEl, options);
            }}
            }});
            </script>
            """))
        return pf.RawBlock(result, format="html")
    return None
Exemple #9
0
def avm(elem, doc):
    """
    The actual panflute style pandoc filter
    """
    if isinstance(elem, pf.CodeBlock):
        if "<cx" in elem.text:
            if doc.format == 'latex':
                return pf.RawBlock(CreateAvm(elem.text, "tex"), "latex")
            elif doc.format == 'html':
                return pf.RawBlock(CreateAvm(elem.text, "html"), "html")
Exemple #10
0
def collapse(elem, doc):
    if isinstance(elem, pf.CodeBlock) and "html" in doc.format:
        content = [
            pf.RawBlock("<details>", format="html"),
            pf.RawBlock("""
                <summary onclick="this.innerHTML == ' Show code ' ? this.innerHTML = ' Hide code ': this.innerHTML = ' Show code '"> Show code </summary>
                """),
            elem,
            pf.RawBlock("</details>", format="html"),
        ]
        div = pf.Div(*content, classes=["collapsible_code"])
        return div
Exemple #11
0
def h_html_footnote(e, doc):
    """Handle footnotes with bigfoot"""
    if not isinstance(e, pf.Note) or doc.format != "html": return None
    htmlref = rf'<sup id="fnref:{doc.footnotecounter}"><a href="#fn:{doc.footnotecounter}" rel="footnote">{doc.footnotecounter}</a></sup>'
    htmlcontent_before = rf'<li class="footnote" id="fn:{doc.footnotecounter}"><p>'
    htmlcontent_after = rf'<a href="#fnref:{doc.footnotecounter}" title="return to article"> ↩</a><p></li>'
    doc.footnotecounter += 1
    conts = pf.Div(*e.content)
    doc.footnotecontents += [
        pf.RawBlock(htmlcontent_before, format="html")
    ] + [conts] + [pf.RawBlock(htmlcontent_after, format="html")]
    return pf.RawInline(htmlref, format="html")
Exemple #12
0
def codeblock(elem, doc):
    if not isinstance(elem, pf.CodeBlock):
        return None

    if not elem.classes:
        elem.classes.append('default')

    result = elem

    if any(cls in elem.classes
           for cls in ['cpp', 'default', 'diff']) and escape_char in elem.text:
        datadir = doc.get_metadata('datadir')
        syntaxdir = os.path.join(datadir, 'syntax')

        text = pf.convert_text(elem,
                               input_format='panflute',
                               output_format=doc.format,
                               extra_args=[
                                   '--syntax-definition',
                                   os.path.join(syntaxdir, 'isocpp.xml')
                               ])

        def repl(match_obj):
            match = match_obj.group(1)
            if not match:  # @@
                return match_obj.group(0)
            if match.isspace():  # @  @
                return match

            if doc.format == 'latex':
                # Undo `escapeLaTeX` from https://github.com/jgm/skylighting
                match = match.replace('\\textbackslash{}', '\\') \
                             .replace('\\{', '{') \
                             .replace('\\}', '}')

            plain = pf.Plain(*pf.convert_text(match)[0].content)
            return pf.convert_text(plain.walk(divspan, doc),
                                   input_format='panflute',
                                   output_format=doc.format)

        result = pf.RawBlock(escape_span.sub(repl, text), doc.format)

    if 'diff' not in elem.classes:
        return result

    # For HTML, this is handled via CSS in `data/template/wg21.html`.
    command = '\\renewcommand{{\\{}}}[1]{{\\textcolor[HTML]{{{}}}{{#1}}}}'
    return pf.Div(
        pf.RawBlock(
            command.format('VariableTok', doc.get_metadata('addcolor')),
            'latex'),
        pf.RawBlock(command.format('StringTok', doc.get_metadata('rmcolor')),
                    'latex'), result)
Exemple #13
0
def alteration(elem, doc):
    text = pf.stringify(elem).strip()
    is_relevant = isinstance(elem, pf.Para) and text.startswith("::alteration-")

    if not is_relevant:
        return

    if text.endswith("-begin"):
        return pf.RawBlock("{\\color{alterationcolor}", format="latex")

    if text.endswith("-end"):
        return pf.RawBlock("}", format="latex")
Exemple #14
0
class DocxPagebreak(object):
    pagebreak = pf.RawBlock("<w:p><w:r><w:br w:type=\"page\" /></w:r></w:p>",
                            format="openxml")
    sectionbreak = pf.RawBlock(
        "<w:p><w:pPr><w:sectPr><w:type w:val=\"nextPage\" /></w:sectPr></w:pPr></w:p>",
        format="openxml")
    toc = pf.RawBlock(r"""
<w:sdt>
    <w:sdtContent xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
        <w:p>
            <w:r>
                <w:fldChar w:fldCharType="begin" w:dirty="true" />
                <w:instrText xml:space="preserve">TOC \o "1-3" \h \z \u</w:instrText>
                <w:fldChar w:fldCharType="separate" />
                <w:fldChar w:fldCharType="end" />
            </w:r>
        </w:p>
    </w:sdtContent>
</w:sdt>
""",
                      format="openxml")

    def action(self, elem, doc):
        if isinstance(elem, (pf.Para, pf.Plain)):
            for child in elem.content:
                if isinstance(child, pf.Str) and child.text == r"\newpage":
                    if (doc.format == "docx"):
                        pf.debug("Page Break")
                        elem = self.pagebreak
        if isinstance(elem, pf.RawBlock):
            if elem.text == r"\newpage":
                if (doc.format == "docx"):
                    pf.debug("Page Break")
                    elem = self.pagebreak
            # elif elem.text == r"\newsection":
            #     if (doc.format == "docx"):
            #         pf.debug("Section Break")
            #         elem = self.sectionbreak
            #     else:
            #         elem = []
            elif elem.text == r"\toc":
                if (doc.format == "docx"):
                    pf.debug("Table of Contents")
                    para = [
                        pf.Para(pf.Str("Table"), pf.Space(), pf.Str("of"),
                                pf.Space(), pf.Str("Contents"))
                    ]
                    div = pf.Div(*para,
                                 attributes={"custom-style": "TOC Heading"})
                    elem = [div, self.toc]
                else:
                    elem = []
        return elem
def process_code_latex(code, doc):
    # type: (pf.CodeBlock, Doc) -> Element
    if doc.format not in ("tex", "latex"):
        return None
    if not isinstance(code, pf.CodeBlock):
        return None
    # TODO line wrapping
    return [
        pf.RawBlock("\\begin{mdframed}", format=doc.format),
        code,
        pf.RawBlock("\\end{mdframed}", format=doc.format),
    ]
Exemple #16
0
class DocxPagebreak(object):
    pagebreak = pf.RawBlock("<w:p><w:r><w:br w:type=\"page\" /></w:r></w:p>", format="openxml")
    sectionbreak = pf.RawBlock("<w:p><w:pPr><w:sectPr><w:type w:val=\"nextPage\" /></w:sectPr></w:pPr></w:p>",
                               format="openxml")
    toc = r"""
<w:sdt>
<w:sdtPr>
  <w:docPartObj>
    <w:docPartGallery w:val="{}" />
  </w:docPartObj>
</w:sdtPr>
<w:sdtContent xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  <w:p>
    <w:pPr>
      <w:pStyle w:val="TOCHeading" />
    </w:pPr>
    <w:r>
      <w:t xml:space="preserve">{}</w:t>
    </w:r>
  </w:p>
  <w:p>
    <w:r>
      <w:fldChar w:fldCharType="begin" w:dirty="true" />
      <w:instrText xml:space="preserve">TOC \o "1-3" \h \z \u</w:instrText>
      <w:fldChar w:fldCharType="separate" />
      <w:fldChar w:fldCharType="end" />
    </w:r>
  </w:p>
</w:sdtContent>
</w:sdt>
"""

    def action(self, elem, doc):
        toctitle = doc.get_metadata('toc-title', "Table of Contents")
        if isinstance(elem, pf.RawBlock):
            if elem.text == r"\newpage":
                if (doc.format == "docx"):
                    pf.debug("Page Break")
                    elem = self.pagebreak
            # elif elem.text == r"\newsection":
            #     if (doc.format == "docx"):
            #         pf.debug("Section Break")
            #         elem = self.sectionbreak
            #     else:
            #         elem = []
            elif elem.text == r"\toc":
                if (doc.format == "docx"):
                    pf.debug("Table of Contents")
                    elem = pf.RawBlock(self.toc.format(toctitle,toctitle),format="openxml")
                else:
                    elem = []
        return elem
Exemple #17
0
def handle_code_block(elem):
    try:
        language = elem.classes[0]
    except IndexError:
        language = 'python'

    begin_raw = '\\begin{{{}code}}'.format(language)
    end_raw = '\\end{{{}code}}'.format(language)

    begin_block = pf.RawBlock(begin_raw, format='tex')
    content = pf.RawBlock(elem.text, format='tex')
    end_block = pf.RawBlock(end_raw, format='tex')

    return [begin_block, content, end_block]
Exemple #18
0
def handleHeader(e, doc):
    """

    :param e:
    :param doc:
    :return:
    """
    global blocktag
    tag = blocktag
    blocktag = None
    if "endblock" in e.classes:
        return pf.RawBlock("\\end{" + tag + "}\n")
    if tag:
        return [pf.RawBlock("\\end{" + tag + "}\n", "latex"), e]
Exemple #19
0
def h_html_code_block(e, doc):
    """HTML code block"""
    if not isinstance(e, pf.CodeBlock) or doc.format != "html":
        return None
    if "algorithm" in e.classes:
        return None
    if not "full" in e.classes:
        return None
    label = labelref(e, doc)
    name, number, file = get_full_label(label, doc)
    title = e.attributes.get("title", "")
    before = rf"<p><i>Figure {number}: {title}</i></p>" + "\n"
    after = r"<p></p>"
    return pf.Div(pf.RawBlock(before, format='html'), e,
                  pf.RawBlock(after, format='html'))
Exemple #20
0
def action(elem, doc):
    if isinstance(elem, panflute.Header):
        if elem.level == 1:
            text = panflute.stringify(elem)
            rainbow_header = '<h1 id="' + text + '">' + rainbowify(
                text) + '</h1>'
            return (panflute.RawBlock(rainbow_header))
Exemple #21
0
def fenced_latex(options, data, element, doc):
    raw_caption = options.get('caption')
    caption = pf.convert_text(options.get('caption'),
                              extra_args=['--biblatex'],
                              input_format='markdown',
                              output_format='latex') if raw_caption else None

    raw_shortcaption = options.get('shortcaption')
    shortcaption = pf.convert_text(
        options.get('shortcaption'),
        extra_args=['--biblatex'],
        input_format='markdown',
        output_format='latex') if raw_shortcaption else None

    latex = CODEBLOCK.render({
        'floating': options.get('caption'),
        'placement': options.get('placement'),
        'options': options.get('mintedopts'),
        'language': options.get('language'),
        'content': data,
        'caption': caption,
        'shortcaption': shortcaption,
        'identifier': options.get('identifier', '')
    })
    return pf.RawBlock(latex, format='latex')
def csv_to_table_markdown(options, data, use_grid_tables):
    """Construct pipe/grid table directly.
    """
    # prepare table in list from data/include
    table_list = read_csv(
        options.get('include', None),
        data,
        encoding=options.get('include-encoding', None),
        csv_kwargs=options.get('csv-kwargs', dict()),
    )

    # regularize table: all rows should have same length
    n_col = regularize_table_list(table_list)

    # parse alignment
    alignment = parse_alignment(options.get('alignment', None), n_col)
    del n_col
    # get caption
    caption = options.get('caption', None)

    text = csv_to_grid_tables(
        table_list, caption, alignment, (len(table_list) > 1 and options.get(
            'header', True))) if use_grid_tables else csv_to_pipe_tables(
                table_list, caption, alignment)

    raw_markdown = options.get('raw_markdown', False)
    if raw_markdown:
        return panflute.RawBlock(text, format='markdown')
    else:
        return panflute.convert_text(text)
Exemple #23
0
def handleHeaderBlockLevel(e, doc):
    """

    :param e:
    :param doc:
    :return:
    """
    global blocktag
    tag = blocktag
    blocktag = None
    before = None
    if tag:
        before = pf.RawBlock("\\end{" + tag + "}\n", "latex")
        if "endblock" in e.classes:
            return before

    for blocktype in BLOCKCLASSES:
        if blocktype in e.classes:
            logging.debug("BLOCKTYPE:" + blocktype)
            if not isinstance(e.content, pf.ListContainer):
                logging.debug("CONTENT:" + pf.stringify(e.content))
                tag = TEX_BLOCKCLASSES_TAG[blocktype]
                elem = pf.Div()
                elem.content = [
                    pf.Plain(pf.RawInline("\n\\begin{" + tag + "}[", "latex"),
                             e.content, pf.RawInline("]\n", "latex"))
                ]

                blocktag = tag

                if before:
                    return [before, elem]
                return elem
            else:
                logging.debug("CONTENT: Listcontainer")
Exemple #24
0
def indexhtml(doc):
    """Generate HTML index for title page"""
    keys = sorted(doc.toc.keys(), key=placekey)

    def depth(key):
        return key.count(".")

    HTML = fr"""<ul>"""
    for k in keys:
        e = doc.toc[k]
        title = e["title"]
        file = os.path.splitext(e["filename"])[0]
        base = doc.get_metadata("binarybaseurl", "")
        if depth(k) > 0:
            continue
        entry = dedent(fr"""
                <li><a href="{file+'.html'}"><b>Chapter {k}:</b> {title}</a>
                <small>(<a href="{base+'/'+file+'.pdf'}"><i class="fas fa-file-pdf"></i>PDF: best formatting</a> ,
                <a href="{base+'/'+file+'.docx'}"><i class="fas fa-file-word"></i>Word: buggy</a>)</small>
                </li>
                """)
        HTML += entry
    HTML += r"""</ul>"""
    doc.metadata["indexcontents"] = pf.MetaBlocks(
        pf.RawBlock(HTML, format="html"))
Exemple #25
0
def gb4e(lst):
    """
    Convert an example list into a series of gb4e-formatted interlinear
    glosses.

    Because example list references are replaced at parsing by Pandoc, the
    normal syntax of (@foo) cannot be used for labels; instead, a label syntax
    similar to that used for headers (and tables and figures with
    pandoc-crossref) is used, namely a {#ex:foo} inserted after the
    translation, which will be stripped and replaced with a LaTeX label on the
    relevant example.
    """

    latex = "\\begin{exe}\n"
    for li in lst.content:
        lines = break_plain(li.content[0])
        if len(lines) != 3: continue

        orig, gloss, trans = map(partial(pf.stringify, newlines=False), lines)
        gloss = smallcapify(gloss)

        label_match = label_re.search(trans)
        if label_match:
            label = label_match.group(1)
            trans = trans[:label_match.start() - 1]

            latex += gb4e_fmt_labelled.format(orig, gloss, trans, label=label)
        else:
            latex += gb4e_fmt.format(orig, gloss, trans)

    latex += "\\end{exe}"
    return pf.RawBlock(latex, format='latex')
Exemple #26
0
def fenced_blockquote(options, data, element, doc, language):
    values = {
        'language': language,
        'mintedopts': '',
        'caption': '',
        'identifier': '',
        'text': data
    }

    caption = options.get('caption')
    if caption:
        converted_caption = pf.convert_text(caption,
                                            extra_args=['--biblatex'],
                                            input_format='markdown',
                                            output_format='latex')
        values['caption'] = r'\caption{{{}}}'.format(converted_caption)

    identifier = options.get('identifier')
    if identifier:
        values['identifier'] = r'\label{{{}}}'.format(identifier)

    mintedopts = options.get('mintedopts', '')
    if mintedopts:
        values['mintedopts'] = r'[{}]'.format(mintedopts)

    tex = TEMPLATE_CODEBLOCK.safe_substitute(values)
    return pf.RawBlock(tex, format='latex')
    def _test_content_box(self, handler, element_classes, env_args=None):
        # some latex content in the environment
        elem_content = r"""
            \begin{itemize}
                \item{item1}
                \item{item2}
            \end{itemize}
        """

        # should return a div with the given classes
        self.doc.content.extend([pf.RawBlock(elem_content, format="latex")])
        elem = self.doc.content[0]  # this sets up elem.parent
        div = handler(elem_content, env_args, elem)
        self.assertIsInstance(div, pf.Div)
        self.assertEqual(div.classes, element_classes)
        for cls in element_classes:
            with self.subTest(cls=cls):
                self.assertIn(cls, div.classes)

        # and the content of the environment should be parsed correctly
        bullet_list = div.content[0]
        self.assertIsInstance(bullet_list, pf.BulletList)
        self.assertEqual(
            bullet_list.content[0].content[0].content[0].content[0].text,
            "item1",
        )
        return div
 def test_handle_html(self):
     """html"""
     doc = pf.Doc(metadata={"lang": "en"})
     html = r"""<p>
     <h3 class="start">Suitable browsers</h3>
     The following browsers can be used for the course: Firefox, Internet
     Explorer, Chrome, Safari, Opera.<br />
     Some other browsers have difficulties rendering our unit pages
     correctly.
     <br />
     We recommend using only the fully updated latest versions of these
     browsers. In particular, the course cannot be completed with obsolete
     browsers such as Internet Explorer 8 or earlier.
     </p>"""
     elem_content = r"\\begin{{html}}\n{}\n\\end{{html}}" "".format(html)
     doc.content.extend([pf.RawBlock(elem_content, format="latex")])
     elem = doc.content[0]  # this sets up elem.parent
     ret = self.environments.handle_html(html, [], elem)
     header = ret[0]
     self.assertIsInstance(header, pf.Header)
     self.assertEqual(header.content[0].text, "Suitable")
     self.assertEqual(header.content[2].text, "browsers")
     para = ret[1]
     self.assertIsInstance(para, pf.Para)
     self.assertEqual(len(para.content), 107)
     self.assertEqual(para.content[106].text, "earlier.")
    def test_handle_mxinfo_math_title(self):
        """MXInfo with Math in title"""
        doc = pf.Doc(metadata={"lang": "en"})
        elem_content = r"""
        \begin{MXInfo}{Ableitung $x^n$}
        Foo bar
        \end{MXInfo}
        """
        doc.content.extend([pf.RawBlock(elem_content, format="latex")])
        elem = doc.content[0]  # this sets up elem.parent
        ret = self.environments.handle_mxinfo("Foo bar", ["Ableitung $x^n$"],
                                              elem)

        self.assertIsInstance(ret, pf.Div)

        header = ret.content[0]
        self.assertIsInstance(header, pf.Header)
        self.assertIsInstance(header.content[0], pf.Str)
        self.assertEqual(header.content[0].text, "Ableitung")
        self.assertIsInstance(header.content[1], pf.Space)
        self.assertIsInstance(header.content[2], pf.Math)
        self.assertEqual(header.content[2].text, "x^n")
        self.assertEqual(header.content[2].format, "InlineMath")

        para = ret.content[1]
        self.assertIsInstance(para.content[0], pf.Str)
        self.assertEqual(para.content[0].text, "Foo")
        self.assertIsInstance(para.content[1], pf.Space)
        self.assertIsInstance(para.content[2], pf.Str)
        self.assertEqual(para.content[2].text, "bar")
    def test_handle_mtest_section_title(self):
        """MTest"""
        doc = pf.Doc(metadata={"lang": "en"})
        elem_content = r"""
        \begin{MTest}{Abschlusstest Kapitel \arabic{section}}
            Foo bar
        \end{MXContent}"""
        doc.content.extend([pf.RawBlock(elem_content, format="latex")])
        elem = doc.content[0]  # this sets up elem.parent

        ret = self.environments.handle_mtest(
            "Foo bar", [r"Abschlusstest Kapitel \arabic{section}"], elem)

        self.assertEqual(len(ret), 2)

        header = ret[0]
        self.assertIsInstance(header, pf.Header)
        self.assertEqual(pf.stringify(header), "Abschlusstest")

        para = ret[1]
        self.assertIsInstance(para.content[0], pf.Str)
        self.assertEqual(para.content[0].text, "Foo")
        self.assertIsInstance(para.content[1], pf.Space)
        self.assertIsInstance(para.content[2], pf.Str)
        self.assertEqual(para.content[2].text, "bar")