Пример #1
0
 def _nonnormative(name):
     _wrap(
         pf.Span(pf.Str('[ '), pf.Emph(pf.Str('{}:'.format(name.title()))),
                 pf.Space),
         pf.Span(pf.Str(' — '),
                 pf.Emph(pf.Str('end {}'.format(name.lower()))),
                 pf.Str(' ]')))
Пример #2
0
 def test_valid_content_strs_and_spans_html(self):
     doc = common.MockDoc('html')
     span1 = pf.Span(pf.Str('a'))
     str1 = pf.Str('b')
     span2 = pf.Span(pf.Str('c'))
     span = pf.Span(span1, str1, span2, classes=['gloss'])
     gloss.parse(span, doc)
     self.assertEqual(pf.stringify(span), 'a<br/>b<br/>c')
Пример #3
0
 def test_valid_content_strs_and_spans_latex(self):
     doc = common.MockDoc('latex')
     span1 = pf.Span(pf.Str('a'))
     str1 = pf.Str('b')
     span2 = pf.Span(pf.Str('c'))
     str2 = pf.Str('d')
     span = pf.Span(span1, str1, span2, str2, classes=['phonrule'])
     phonrule.parse(span, doc)
     self.assertEqual(pf.stringify(span), '\\phonb{a}{b}{c}{d}')
Пример #4
0
 def test_valid_content_strs_and_spans(self):
     doc = common.MockDoc('html')
     span1 = pf.Span(pf.Str('a'))
     str1 = pf.Str('b')
     span2 = pf.Span(pf.Str('c'))
     str2 = pf.Str('d')
     span = pf.Span(span1, str1, span2, str2, classes=['phonrule'])
     phonrule.parse(span, doc)
     self.assertEqual(pf.stringify(span), 'a -&gt; b/c_d')
Пример #5
0
def action(elem, doc):
    """Remove empty headings from Vimwiki file."""
    if isinstance(elem, pf.ListItem):
        elem.walk(start2done1)
    if isinstance(elem, pf.BulletList) or isinstance(elem, pf.OrderedList):
        # pf.debug(elem)
        elem.replace_keyword("[S]", pf.Span(classes=["done1"]))
        elem.replace_keyword("[-]", pf.Span(classes=["doneX"]))
        return elem
    return None
Пример #6
0
 def test_valid_content_strs_and_spans_latex(self):
     doc = common.MockDoc('latex')
     span1 = pf.Span(pf.Str('a'))
     str1 = pf.Str('b')
     span2 = pf.Span(pf.Str('c'))
     span = pf.Span(span1, str1, span2, classes=['gloss'])
     gloss.parse(span, doc)
     self.assertEqual(
         pf.stringify(span),
         '\\begin{exe}\n\\ex\n\\gll a\\\\\nb\\\\\n\\trans c\n\\end{exe}')
Пример #7
0
def action(elem, doc):
    global collect_tags, tag_sequence
    if isinstance(
            elem,
            pf.Header) and "course-title" in elem.classes and collect_tags:
        # this is a course separator, we should reset state
        build_course_barcode(doc)
        collect_tags = False
        tag_sequence = []
    if isinstance(elem,
                  pf.Header) and pf.stringify(elem) == "Learning objectives":
        collect_tags = elem.index + 1
    if isinstance(elem, pf.Span) and "used-in" in elem.attributes:
        courses = ", ".join(elem.attributes['used-in'].split())
        used_in = pf.Span(pf.Str(f"(Depended on by {courses})"))
        elem.content.append(pf.Space())
        elem.content.append(used_in)
    if isinstance(elem, pf.Span) and "outcomes" in elem.attributes:
        outcomes = elem.attributes["outcomes"].split()
        outcome_spans = []
        for outcome in outcomes:
            # only include outcomes in the sequence if there's an ID
            if collect_tags:
                tag_sequence.append(outcome)

            outcome_spans.append(pf.Space())

            if outcome not in outcome_colours:
                outcome_colours[outcome] = colours.popleft()

            colour = outcome_colours[outcome]
            if doc.format in ('html', 'html5'):
                outcome_spans.append(
                    pf.Span(
                        pf.Str(outcome),
                        attributes={
                            'style':
                            f"color:{colour[0]};background-color:{colour[1]};border:1px solid black;"
                        }))
            elif doc.format == 'latex':
                outcome_spans.append(
                    pf.Span(
                        pf.RawInline(f"""
                    \\tcbox[on line,arc=0pt, outer arc=0pt,boxsep=0pt,boxrule=1pt,top=2pt,bottom=2pt,left=1pt,right=1pt,colback={colour[1]}]{{
                        \\color{{{colour[0]}}}{outcome}
                    }}
                    """,
                                     format='latex')))

        elem.content.extend(outcome_spans)
Пример #8
0
def parse_citations(elem, doc):
    if isinstance(elem, pf.Link) and "table_note" not in elem.classes:
        text = pf.stringify(elem)

        if link_is_cite.search(text):
            return to_cite(text, doc)

    elif (
        hasattr(elem, "text")
        and len(elem.text) > 0
        and not isinstance(elem.parent, pf.Link)
        and not isinstance(elem, (pf.Code, pf.CodeBlock))
    ):

        text = elem.text

        if str_is_cite.search(text):
            content = []

            for s, c in utils.re_split(str_is_cite, text):
                content.append(s)

                if c:
                    content.append(to_cite(c, doc))

            return pf.Span(*content)
Пример #9
0
    def handle_mlabel(self, cmd_args, elem):
        # pylint: disable=line-too-long
        r"""Handle ``\MLabel`` command.

        Will search for the previous header element and update its ID to the
        ID defined in the command. Otherwise proceed like
        ``\MDeclareSiteUXID``.

        Hides identifier in fake element like
        (:py:func:`innoconv_mintmod.mintmod_filter.commands.Commands.handle_mdeclaresiteuxid`).
        """
        identifier = cmd_args[0]

        # Ignore MLabel in test sections as this would mess up the previous
        # section caption.
        if "Abschlusstest" in identifier or "Ausgangstest" in identifier:
            return []

        # attach identifier to previous element
        try:
            get_remembered(elem.doc, "label").identifier = identifier
            return []
        except AttributeError:
            pass

        # otherwise return a div/span with ID that is parsed in the parent
        # process
        if isinstance(elem, pf.Block):
            ret = pf.Div()
        else:
            ret = pf.Span()
        ret.identifier = "{}-{}".format(INDEX_LABEL_PREFIX, identifier)
        ret.classes = [INDEX_LABEL_PREFIX]
        ret.attributes = {"hidden": "hidden"}
        return ret
Пример #10
0
def to_inline(elem, classes=[], attributes={}):
    """Convert any given pandoc element to inline element(s). Some information
    may be lost."""

    if not classes:
        classes = getattr(elem, "classes", [])
    if not attributes:
        attributes = getattr(elem, "attributes", {})

    if isinstance(elem, pf.Inline):
        return elem
    if isinstance(elem, pf.CodeBlock):
        return pf.Code(elem.text, classes=classes, attributes=attributes)
    if isinstance(elem, pf.RawBlock):
        return pf.RawInline(elem.text, format=elem.format)

    elems = []
    if isinstance(elem, pf.Block):
        elems = elem.content
    elif isinstance(elem, list):
        elems = elem

    # dont nest too many spans
    if len(elems) == 1:
        return to_inline(elems[0], classes=classes, attributes=attributes)

    ret = [to_inline(x, classes=classes, attributes=attributes) for x in elems]

    return pf.Span(*ret, classes=classes, attributes=attributes)
Пример #11
0
def finalize(doc):
    content = doc.content

    colour_boxes = []
    count = 0
    for t in tag_sequence:
        colour = outcome_colours[t]
        if doc.format in ('html', 'html5'):
            div = pf.Span(
                attributes={
                    'style':
                    f"width:4px;height:40px;background-color:{colour[1]};float:left"
                })
        elif doc.format == 'latex':
            div = pf.RawInline(
                f"\\tcbox[tcbox width=forced center,boxrule=0mm,before=,after=,left=0mm,right=0mm,width=1mm,height=4em,arc=0mm,colframe={colour[1]},colback={colour[1]}]{{}}",
                format='latex')
        colour_boxes.append(div)

    colour_block = pf.Div(pf.Plain(*colour_boxes),
                          attributes={'style': 'height:45px'})
    barcodes.append((collect_tags, colour_block))

    # Now insert them in reverse order (biggest insertion point first) so that
    # when we insert things into the document, stuff below doesn't get shifted
    # down.
    barcodes.reverse()
    for (spot, block) in barcodes:
        content.insert(spot, block)
Пример #12
0
def table_matrix_to_pf(matrix, doc):
    options = matrix[0]
    t_kwargs = options
    caption = matrix[1]
    table = matrix[2]
    footnotes = [i for i in list_to_elems([matrix[3]])]

    row_cnt = len(table)

    rows = []
    new_col_cnt = 0
    old_col_cnt = None

    for r, row in enumerate(table):
        cells = []
        r_kwargs = row[1]

        for c, cell in enumerate(row[0]):
            if isinstance(cell, tuple):
                c_args = cell[0]
                c_kwargs = cell[1]

                col_span = utils.check_type(c_kwargs.get("col_span", 1), int)

                repeat = 1

                if "repeat" in c_kwargs:
                    repeat = utils.check_type(c_kwargs.get("repeat", 1), int)
                    del c_kwargs["repeat"]

                for _ in range(repeat):
                    new_col_cnt += 1
                    cells.append(TableCell(*list_to_elems(c_args), **c_kwargs))

                    for i in range(1, col_span):
                        new_col_cnt += 1
                        cells.append(TableCell(pf.Null(), covered=True))
            else:
                new_col_cnt += 1
                cells.append(TableCell(*list_to_elems([cell])))

        if old_col_cnt is None:
            old_col_cnt = new_col_cnt

        if new_col_cnt != old_col_cnt:
            raise IndexError(f"Expected {old_col_cnt} columns "
                             f"but got {new_col_cnt} in {row}")

        new_col_cnt = 0

        rows.append(TableRow(*cells, **r_kwargs))

    if caption:
        t_kwargs["caption"] = [pf.Span(pf.Str(caption))]

    return pf.Div(
        Table(*rows, col_cnt=old_col_cnt, row_cnt=row_cnt, **t_kwargs),
        *footnotes,
        classes=["custom_table"],
    )
def filter_eqref(elem, doc):
  """
  [eq:...] の参照タグを MathJax 参照に置き換える
  """
  if isinstance(elem, pf.Link) and elem.url[:4] == '#eq:':
    ref_id_eq = elem.url[1:]
    return pf.Span(pf.RawInline('(\\ref{' + ref_id_eq + '})'), attributes={'data-reference-type': 'ref', 'data-reference': f'{ref_id_eq}'})
Пример #14
0
def _span(elem, doc):
    text = elem.text

    if doc.format == "latex":
        return pf.RawInline(f"{{{text}}}", format="latex")
    else:
        return pf.Span(*elem.content)
Пример #15
0
def action(e, doc):
    if isinstance(e, pf.Image) and (doc.format == 'latex') and ('parbox' in e.classes):
        subs = {'image':e.url}
        before = pf.RawInline(TEX_BEFORE, format='latex')
        after = pf.RawInline(TEX_AFTER.safe_substitute(subs), format='latex')
        span = pf.Span(before, *e.content, after, classes=e.classes, identifier=e.identifier, attributes=e.attributes)
        return(span)
Пример #16
0
def render_citations(elem, doc, string=False):
    if isinstance(elem, pf.Cite):
        if doc.format == "latex" and not doc.get_metadata(
            "doit_citeproc_for_latex", True
        ):

            latex_commands = []
            latex_command = "\\autocite{{{ids}}}"

            if hasattr(elem, "latex_command") and elem.latex_command:
                for command in elem.latex_command:
                    head = "" if command.startswith("\\") else "\\cite"
                    latex_command = "{head}{command}{{{{{{ids}}}}}}".format(
                        head=head, command=command
                    )

                    latex_commands.append(latex_command)
            else:
                latex_commands.append(latex_command)

            citations = ",".join([c.id for c in elem.citations])

            raw = "".join(lc.format(ids=citations) for lc in latex_commands)

            if string:
                return raw
            else:
                return pf.RawInline(raw, format="latex")
        else:
            if hasattr(elem, "latex_command") and "author" in elem.latex_command:

                names = []
                amount_citations = len(elem.citations)

                for i in range(1, amount_citations + 1):
                    citation = elem.citations[i - 1]
                    citation = doc.bibliography.get(citation.id, False)

                    if citation:
                        names_list = citation.get(
                            "author", citation.get("editor", False)
                        )

                        if names_list:
                            names.extend(utils.format_names(names_list))

                            if not i == amount_citations:
                                names.extend([pf.Str(", "), pf.Space])

                if names:
                    if elem.next:
                        if pf.stringify(names[-1]).endswith(".") and pf.stringify(
                            elem.next
                        ).startswith("."):
                            names[-1] = pf.Str(pf.stringify(names[-1])[:-1])

                            return pf.Span(*names)

            return pf.Cite(citations=elem.citations)
Пример #17
0
def action(elem, doc):
    if isinstance(elem, pf.ListItem) and elem.content and isinstance(
            elem.content[0], pf.Plain):
        plain = elem.content[0]

        stringy = pf.stringify(elem)
        matches = tag_pattern.findall(stringy)
        identifier = None
        outcome = None

        # strip the tags from the element before we proceed any further
        for tag in matches:
            elem = elem.replace_keyword(tag, pf.Space())

        # strip the trailing whitespace (this is equivalent to a trim operation)
        while type(plain.content[-1]) in (pf.Space, pf.SoftBreak):
            del plain.content[-1]

        # gather all of the tags/IDs on the learning objective into something
        # that we can write out to an attribute on the span.
        outcomes = []
        identifiers = []
        courses = []
        for tag in matches:
            if "&" in tag:
                # this is not a tag, it's a course reference
                courses.append(tag[1:-1])
            elif "#" in tag:
                identifiers.append(tag[tag.index("#") + 1:-1])
                outcomes.append(tag[:tag.index("#")] + ":")
            else:
                outcomes.append(tag)
        outcomes = " ".join(outcomes)
        courses = " ".join(courses)

        if len(identifiers) == 1:
            identifier = identifiers[0]
        elif len(identifiers) > 1:
            pf.debug(f"Found multiple IDs: {identifiers}")
            identifier = identifiers[0]
        else:
            identifier = ""

        # Take the existing contents of the `pf.Plain` that's the first child
        # of the `pf.ListItem` and embed that into a `pf.Span`. Then make the
        # `pf.Span` the only child of the `pf.Plain`.
        if matches:
            span = pf.Span(*plain.content,
                           identifier=identifier,
                           attributes={
                               "outcomes": outcomes,
                               "course": pf.stringify(doc.metadata["title"])
                           })
            if courses:
                span.attributes["used-in"] = courses
            plain.content.clear()
            plain.content.append(span)

        return elem
Пример #18
0
    def test_invalid_content(self):
        doc = common.MockDoc('html')

        span = pf.Span(classes=['gloss'])
        with self.assertRaisesRegexp(Exception, 'invalid gloss syntax'):
            gloss.parse(span, doc)

        span = pf.Span(pf.Str('a'), pf.Str('b'), classes=['gloss'])
        with self.assertRaisesRegexp(Exception, 'invalid gloss syntax'):
            gloss.parse(span, doc)

        span = pf.Span(pf.Str('a'),
                       pf.Str('b'),
                       pf.Str('c'),
                       pf.Str('d'),
                       classes=['gloss'])
        with self.assertRaisesRegexp(Exception, 'invalid gloss syntax'):
            gloss.parse(span, doc)
def filter_hatena_mathjax(elem, doc):
  if isinstance(elem, pf.Math):
    math_expr = elem.text
    math_expr = re.sub('^\\\\begin{aligned}', r'\\begin{align}', math_expr)
    math_expr = re.sub('\\\\end{aligned}', r'\\end{align}', math_expr)
    math_code = pf.RawInline('[tex: {}]'.format(math_expr))
    if elem.format == 'DisplayMath':
      return [pf.RawInline('\n'), pf.Span(math_code, classes=['Math', 'DisplayMath']), pf.RawInline('\n')]
    elif elem.format == 'InlineMath':
      return math_code
Пример #20
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
Пример #21
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"],
        )
Пример #22
0
    def test_to_inline(self):
        """It should convert different elements correctly to inline"""

        content1 = pf.Para(pf.Strong(pf.Str("just some text")))
        transformed1 = content1.content[0]

        content2 = pf.Div(
            pf.Para(pf.Strong(pf.Str("again")), pf.Space,
                    pf.Emph(pf.Str("normal"))))

        content3 = pf.Div(
            pf.Para(
                pf.Span(pf.Str("foo"), classes=["1st-span-class"]),
                pf.Span(
                    pf.Strong(pf.Str("Unhandled"), pf.Space,
                              pf.Str("command:")),
                    classes=["2nd-span-class"],
                ),
            ),
            pf.CodeBlock(r"\MLFunctionQuestion{10}{sin(x)}{5}{x}{5}{DS2}"),
            classes=["div-class"],
        )

        self.assertEqual(to_inline(content1), transformed1)

        # test if nested inlining works
        il_content2 = to_inline(content2)
        self.assertIsInstance(il_content2.content[0], pf.Strong)
        self.assertEqual(il_content2.content[0].content[0].text, "again")
        self.assertIsInstance(il_content2.content[2], pf.Emph)

        # test if class conservation works and advanced nesting
        il_content3 = to_inline(content3)
        self.assertEqual(len(il_content3.content), 2)
        self.assertEqual(len(il_content3.content[0].content), 2)
        self.assertEqual(il_content3.classes, ["div-class"])
        self.assertEqual(il_content3.content[0].content[0].classes,
                         ["1st-span-class"])
        self.assertEqual(il_content3.content[0].content[1].classes,
                         ["2nd-span-class"])
Пример #23
0
def parse_abbreviations(elem, doc):
    if hasattr(elem, "text") and is_abbreviation.search(elem.text):
        # text = pf.stringify(elem)
        text = elem.text
        content = []
        logger.debug(f"Original element: {elem}")

        for s, c in utils.re_split(is_abbreviation, text):
            logger.debug(f"re_plit of {text} gave {s} > {c}")
            content.append(s)

            if c:
                pl = "1" if elem.text.startswith("++") else ""

                c = c.split("@")

                if len(c) > 1:
                    specifier = c.pop(0)
                else:
                    specifier = ""

                identifier = c.pop(0)

                uppercase = "1" if identifier[
                    0] in string.ascii_uppercase else ""

                # Now we know whether it's uppercase
                identifier = identifier.lower()

                if (identifier not in doc.abbr["aliases"]
                        and identifier[-1] == "s" and not pl
                        and identifier[:-1] in doc.abbr["aliases"]):
                    identifier = identifier[:-1]
                    pl = "1"

                identifier = doc.abbr["aliases"].get(identifier, identifier)

                doc.abbr["used"].append(identifier)

                attributes = {
                    "identifier": identifier,
                    "plural": pl,
                    "uppercase": uppercase,
                    "specifier": specifier,
                }

                content.append(
                    pf.Link(pf.Str(identifier),
                            classes=["abbr"],
                            attributes=attributes))

        return pf.Span(*content)
Пример #24
0
def autounderlined(elem, doc):
    if doc.autounderlined and type(elem) == pf.Link:
        ##Create a span with bogus content but class underline
        span = pf.Span(pf.Str('More'),
                       pf.Space,
                       pf.Str('words.'),
                       classes=["underline"])
        ## Force link's content to become the span's content
        span.content = elem.content
        ## Put the span inside the link
        elem.content = [span]
        #return the modified link
        return elem
Пример #25
0
    def pnum():
        num = pf.stringify(elem)

        if '.' in num:
            num = '({})'.format(num)

        if doc.format == 'latex':
            return pf.RawInline('\\pnum{{{}}}'.format(num), 'latex')
        elif doc.format == 'html':
            return pf.Span(
                pf.RawInline('<a class="marginalized">{}</a>'.format(num), 'html'),
                classes=['marginalizedparent'])

        return pf.Superscript(pf.Str(num))
Пример #26
0
    def handle_mindex(self, cmd_args, elem):
        r"""Handle ``\MIndex`` command.

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

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

        concept = cmd_args[0]
        for repl in MATH_SUBSTITUTIONS:  # can contain LaTeX!
            concept = re.sub(repl[0], repl[1], concept)
        span = pf.Span()
        span.attributes = {INDEX_ATTRIBUTE: concept, "hidden": "hidden"}
        return block_wrap(span, elem)
Пример #27
0
    def _unknown_command_debug(cmd_name, elem):
        """Handle unknown latex commands.

        Output visual feedback about the unknown command.
        """
        classes = ELEMENT_CLASSES["DEBUG_UNKNOWN_CMD"] + [slugify(cmd_name)]
        msg_prefix = pf.Strong(*destringify("Unhandled command:"))
        if isinstance(elem, pf.Block):
            div = pf.Div(classes=classes)
            div.content.extend([pf.Para(msg_prefix), pf.CodeBlock(elem.text)])
            return div
        # RawInline
        span = pf.Span(classes=classes)
        span.content.extend([msg_prefix, pf.Space(), pf.Code(elem.text)])
        return span
Пример #28
0
def create_cite_span(identifiers, rawformat, is_block, prefix="", alt=None):
    """create a cite element from an identifier """
    citations = [pf.Citation(identifier) for identifier in identifiers]
    pmapping = dict(dict(PREFIX_MAP)[prefix])
    classes = list(pmapping["classes"])
    classes += [RAWSPAN_CLASS, CONVERTED_CITE_CLASS, ATTRIBUTE_CITE_CLASS]
    attributes = dict(pmapping["attributes"])
    attributes["raw-format"] = rawformat
    if alt is not None:
        attributes["alt"] = str(alt)
    cite = Cite(citations=citations)
    span = pf.Span(cite, classes=classes, attributes=attributes)
    if is_block:
        return pf.Plain(span)
    else:
        return span
def filter_hatena_image(elem, doc):
  """
  pandoc-crossref のタグを消したりはてなフォトライフにアップロードしたりはてな記法に置換したり
  """
  enable_upload = doc.get_metadata('enable-upload')
  if not enable_upload:
    enable_upload = False

  if isinstance(elem, pf.Image):
    if enable_upload:
      settings_local = Path().cwd().joinpath('settings.json')
      settings_root = Path(__file__).resolve().parent.parent.joinpath('settings/settings.json')
      warnings.warn(settings_local)
      warnings.warn(settings_root)
      if settings_local.exists():
        path_settings = settings_local
      elif settings_root.exists():
        path_settings = settings_root
      else:
         path_settings = None
      if path_settings is not None:
        with settings_root.open('r') as f:
          params_hatenaapi = json.load(f)
      else:
        params_hatenaapi = {k: os.environ.get(k) for k in ('FOTO_API_KEY', 'HATENA_USER', 'HATENA_BLOG')}
      for k in ('FOTO_API_KEY', 'HATENA_USER', 'HATENA_BLOG'):
        if params_hatenaapi.get(k) is None:
          raise KeyError(f'API Parameter `{k}` not found in the settings.')
      uploader = hatena_token(**params_hatenaapi)
      uploader.post_hatenaphoto(elem.url)
      res = ElementTree.fromstring(uploader.last_result.text)
      image_file_id = ':'.join(res.find('hatena:syntax', {'hatena': 'http://www.hatena.ne.jp/info/xmlns#'}).text.split(':')[2:-1])
      image_file_id = f'[f:id:{image_file_id}:plain]'  # TODO: 画像サイズ調整
    else:
      image_file_id = 'INSERT_FILE_ID_HERE'
    ref_ids_img = [x.identifier for x in elem.content if hasattr(x, 'identifier') and x.identifier[:4] == 'fig:']
    if len(ref_ids_img) > 0:  # TODO: 複数ID存在するケースってあるの
      caption_inlines = [x for x in elem.content if isinstance(x, pf.Inline)]
      caption_inlines = [x for x in caption_inlines if not (hasattr(x, 'attributes') and x.attributes.get('label'))]
      caption_plain = str(pf.stringify(pf.Span(*caption_inlines)))
      return [
        pf.RawInline('\n'), pf.RawInline(f'><figure class="figure-image figure-image-fotolife" title="{caption_plain}"><figcaption id="{ref_ids_img[0]}">')
        ] + caption_inlines + [pf.RawInline(f'</figcaption>{image_file_id}</figure><'), pf.RawInline('\n')]
    else:
      return pf.RawInline(image_file_id)
Пример #30
0
def fenced_html(options, data, element, doc):
    identifier = options.get('identifier', '')
    element.identifier = identifier
    caption = options.get('caption', '')
    caption = pf.convert_text(caption,
                              extra_args=['--biblatex'],
                              input_format='markdown',
                              output_format='html')

    caption_span = pf.Plain(
        pf.Span(pf.RawInline(caption), classes=['fencedSourceCodeCaption']))
    code_block = pf.CodeBlock(data,
                              classes=element.classes,
                              attributes=element.attributes)

    return pf.Div(code_block,
                  caption_span,
                  identifier=identifier,
                  classes=['fencedSourceCode'])