def filter_hatena_blockquote(elem, doc):
  if isinstance(elem, pf.BlockQuote):
    quotecomponents = [pf.RawInline('>>'), pf.RawInline('\n')] + list(elem.content[0].content) + [pf.RawInline('\n'), pf.RawInline('<<')]
    return pf.Plain(*quotecomponents)
  elif isinstance(elem, pf.Div) and 'epigraph' in elem.classes:
    epigraph_phrase = elem.content[0]
    epigraph_source = elem.content[1]
    return pf.Plain(*[pf.RawInline(f'>')] + list(epigraph_source.content) + [pf.RawInline('>'), pf.RawInline('\n')] + list(epigraph_phrase.content) + [pf.RawInline('\n'), pf.RawInline('<<')])
Exemple #2
0
def finalize(doc):
	c1 = pf.TableCell(pf.Plain(pf.Str("Element")))
	c2 = pf.TableCell(pf.Plain(pf.Str("Frequency")))
	header = pf.TableRow(c1, c2)
	rows = []
	for tag in doc.counter:
		c1 = pf.TableCell(pf.Plain(pf.Str(tag)))
		c2 = pf.TableCell(pf.Plain(pf.Str(str(doc.counter[tag]))))
		rows.append(pf.TableRow(c1, c2))
	table = pf.Table(*rows, header=header)
	doc.content = [table] # bugbug?
Exemple #3
0
 def _wrap(opening, closing):
     if isinstance(elem, pf.Div):
         if elem.content and isinstance(elem.content[0], pf.Para):
             elem.content[0].content.insert(0, opening)
         else:
             elem.content.insert(0, pf.Plain(opening))
         if elem.content and isinstance(elem.content[-1], pf.Para):
             elem.content[-1].content.append(closing)
         else:
             elem.content.append(pf.Plain(closing))
     elif isinstance(elem, pf.Span):
         elem.content.insert(0, opening)
         elem.content.append(closing)
Exemple #4
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)
Exemple #5
0
 def plain_to_table_cell(string):
     if isinstance(string, bool):
         if not string:
             string = "no"
         else:
             string = "yes"
     return panflute.TableCell(panflute.Plain(panflute.Str(string)))
Exemple #6
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'))
Exemple #7
0
def action(e, doc):
    if not doc.format == 'latex':
        return None

    if isinstance(e, pf.Span) and 'textquote' in e.classes:
        cite = e.attributes.get('cite')
        if cite:
            cite = pf.convert_text(cite,
                                   extra_args=['--biblatex'],
                                   input_format='markdown',
                                   output_format='latex')
        text = pf.convert_text(pf.Plain(e),
                               extra_args=['--biblatex'],
                               input_format='panflute',
                               output_format='latex')
        values = {
            'lang': e.attributes.get('lang'),
            'cite': cite,
            'punct': e.attributes.get('punct'),
            'text': text
        }
        tex = QUOTE.render(values)
        return pf.RawInline(tex, format='latex')

    else:
        return None
Exemple #8
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 #9
0
def list_to_elems(list_):
    for i in list_:
        if isinstance(i, str):
            for e in pf.convert_text(i, "rst"):
                yield e
        else:
            yield pf.Plain(pf.Str(str(i)))
Exemple #10
0
    def header(elem, doc):
        if not isinstance(elem, pf.Plain):
            return None

        return pf.Div(pf.Plain(pf.RawInline('\\centering', 'latex'),
                               pf.Strong(*elem.content)),
                      attributes={'style': 'text-align:center'})
def filter_hatena_toc(elem, doc):
  """
  目次を挿入する場合ははてな記法で自動生成するように置き換え
  """
  if isinstance(elem, pf.RawBlock):
    if elem.format == 'latex' and elem.text == r'\tableofcontents{}':
      return pf.Plain(pf.RawInline('[:contents]'))
Exemple #12
0
def build_header(elem):
    # We use a `pf.RawInline` here because setting the `align`
    # attribute on `pf.Div` does not work for some reason.
    header = pf.Plain(pf.RawInline('<div align="center">', 'html'),
                      pf.Strong(*elem.content), pf.RawInline('</div>', 'html'))
    width = float(
        elem.attributes['width']) if 'width' in elem.attributes else 0
    return header, width
Exemple #13
0
 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)
Exemple #14
0
def action(elem, doc):
    if isinstance(
            elem,
            pf.RawInline) and elem.format == 'tex' and '\pnum{' in elem.text:
        repl = re.sub(r"\\pnum{([^}]+)}", "<small>(\\1)</small>", elem.text)
        return pf.RawInline(repl, 'html')
    if not isinstance(elem, pf.Div) and not isinstance(elem, pf.Span):
        return None

    color_name = None
    tag_name = None
    for cls in elem.classes:
        color_name = cls + 'color'
        if cls == 'add':
            tag_name = 'ins'
        elif cls == 'rm':
            tag_name = 'del'

    if tag_name is None:
        return None

    open_tag = pf.RawInline('<{}>'.format(tag_name), 'html')
    open_color = pf.RawInline('{{\\color{{{}}}'.format(color_name), 'tex')
    close_color = pf.RawInline('}', 'tex')
    close_tag = pf.RawInline('</{}>'.format(tag_name), 'html')

    color = doc.get_metadata(color_name)
    attributes = {} if color is None else {'style': 'color: #{}'.format(color)}

    if isinstance(elem, pf.Div):
        return pf.Div(pf.Plain(open_tag),
                      pf.Plain(open_color),
                      elem,
                      pf.Plain(close_color),
                      pf.Plain(close_tag),
                      attributes=attributes)
    elif isinstance(elem, pf.Span):
        return pf.Span(open_tag,
                       open_color,
                       elem,
                       close_color,
                       close_tag,
                       attributes=attributes)
Exemple #15
0
def action(elem, doc):
    if isinstance(elem, pf.BulletList) and doc.format == 'latex':
        div = pf.Div()
        for item in elem.content.list:
            plain = item.content.list[0]
            key = plain.content.pop(0)
            cv_line_tex = "\cvitem{%s}{%s}{}" % (pf.stringify(key),
                                                 pf.stringify(plain))
            raw_inline = pf.RawInline(cv_line_tex, format='latex')
            div.content.extend([pf.Plain(raw_inline)])
        return div
Exemple #16
0
def figure(options, data, element, doc):

    # Get options
    fn = os.path.abspath(options['source']).replace('\\', '/')
    title = options.get('title', 'Untitled')
    notes = data
    label = options.get('label', os.path.splitext(os.path.basename(fn))[0])

    if doc.format == 'latex':
        subs = {'fn': fn, 'label': label}
        subs['title'] = pf.convert_markdown(title, format='latex')
        subs['notes'] = pf.convert_markdown(notes, format='latex')
        backmatter = doc.get_metadata('format.backmatter', False)
        pagebreak = doc.get_metadata('format.media-pagebreak', False)

        w = options.get('width', 1.0)
        subs['width'] = w
        subs['innerwidth'] = options.get('innerwidth', w) / w
        subs['notesize'] = options.get('notesize', 'small')
        subs['pagebreak'] = '\\clearpage\n' if pagebreak else ''

        text = LATEX_TEMPLATE.safe_substitute(subs)
        ans = pf.RawBlock(text=text, format='latex')

        if backmatter:
            doc.backmatter.append(ans)
            msg = '\hyperref[fig:{}]{{[\Cref{{fig:{}}} Goes Here]}}'
            msg = msg.format(label, label)
            return pf.Plain(pf.Str(msg))
        else:
            return ans
    else:
        title = pf.convert_markdown(title)
        assert len(title)==1, title
        title = (title[0]).items

        notes = pf.Div(*pf.convert_markdown(notes), classes=['note'])
        title_text = pf.stringify(title)
        img = pf.Image(*title, url=fn, title=title_text, identifier=label)
        ans = pf.Div(pf.Plain(img), pf.Plain(pf.LineBreak), notes, classes=['figure'])
        return ans
Exemple #17
0
def list_to_elems(list_):
    for i in list_:
        if isinstance(i, str):
            for e in pf.convert_text(
                    f""".. role:: raw-latex(raw)
   :format: latex

{i}""",
                    "rst",
            ):
                yield e
        else:
            yield pf.Plain(pf.Str(str(i)))
Exemple #18
0
def parse_table_list(markdown, table_list, doc):
    """
    read table in list and return panflute table format
    """
    # make functions local
    to_table_row = pf.TableRow
    if markdown:
        to_table_cell = lambda x: pf.TableCell(*pf.convert_text(x))
    else:
        to_table_cell = lambda x: pf.TableCell(pf.Plain(pf.Str(x)))
    return [
        to_table_row(*[to_table_cell(x) for x in row]) for row in table_list
    ]
Exemple #19
0
def sage(elem, doc):
    elemtype = type(elem)

    if elemtype in [pf.Math, pf.RawInline]:
        contents = replace_sagecommand(elem.text)

        if elemtype == pf.Math:
            return pf.Math(contents, format=elem.format)
        else:
            return pf.RawInline(contents, format=elem.format)

    if elemtype == pf.CodeBlock:

        isSageSilent = 'sagesilent' in elem.classes
        isSageBlock = 'sageblock' in elem.classes
        isSagePlot = 'sageplot' in elem.classes

        code = elem.text
        if isSageBlock or isSagePlot or isSageSilent:
            img_file = get_image_output_filename(code)
            sage_file = get_sage_filename(code)

            if isSagePlot:
                code = code.strip("\n")
                codelist = code.split("\n")
                plot_cmd = codelist.pop()
                code = "\n".join(codelist)
                m = re.search(r"sageplot\[(?P<first_name>.*)\]\((.*)\)",
                              plot_cmd)
                if m == None:
                    para, cmd = "", plot_cmd
                else:
                    para, cmd = m.group(1), m.group(2)
                if len(para) > 0:
                    para = ',' + para
                code += "\n(%s).save(\"%s\"%s)" % (cmd, img_file, para)

            out, err = run_sage(code)

            if isSageSilent:
                return pf.Plain(pf.RawInline("", "tex"))
            elif isSageBlock:
                sys.stderr.write('\n convert markdown \n')
                return pf.convert_text(out)
            else:
                return pf.Para(
                    pf.Image(url=img_file, attributes=elem.attributes))
        if 'latex' in elem.classes:
            out, err, img_file = run_tex(code)

            return pf.Para(pf.Image(url=img_file, attributes=elem.attributes))
Exemple #20
0
def formatCell(text):
	if len(text) < 10 or text.isdigit():
		return pf.Plain(pf.Str(text))
	try:
		text = float(text)
		if text > 0 and text < .001:
			return pf.Plain(pf.Str('%.3E' % text))
		return pf.Plain(pf.Str('%.3f' % text))
	except (ValueError, TypeError):
		# transform links
		elems = []
		lastend = None
		for m in re.finditer(r'\[(.+?)\]\((.+?)\)', text):
			if lastend is None:
				elems.append(pf.Str(text[:m.start()]))
			else:
				elems.append(pf.Str(text[lastend:m.start()]))
			elems.append(pf.Link(pf.Str(m.group(1)), url = m.group(2)))
			lastend = m.end()
		if elems:
			elems.append(pf.Str(text[lastend:]))
			return pf.Plain(*elems)
		return pf.Plain(pf.Str(text))
def process_internal_links(link, doc):
    # type: (Link, Doc) -> Element
    """extract links that point to internal items, e.g. [text](#label)"""
    if not isinstance(link, pf.Link):
        return None
    match = re.match(r'#(.+)$', link.url)
    if not match:
        return None

    return create_cite_span([match.group(1)],
                            "markdown",
                            False,
                            prefix=dict(PREFIX_MAP_LATEX_R).get("cref"),
                            alt=pf.stringify(
                                pf.Plain(*list(link.content))).strip())
Exemple #22
0
def fenced_action(options, data, element, doc):
    # We'll only run this for CodeBlock elements of class 'csv'
    title = options.get('title', 'Untitled Table')
    title = [pf.Str(title)]
    has_header = options.get('has-header', False)

    with io.StringIO(data) as f:
        reader = csv.reader(f)
        body = []
        for row in reader:
            cells = [pf.TableCell(pf.Plain(pf.Str(x))) for x in row]
            body.append(pf.TableRow(*cells))

    header = body.pop(0) if has_header else None
    table = pf.Table(*body, header=header, caption=title)
    return table
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 action(e, doc):
    if isinstance(e, pf.Header) and 'unnumbered' in e.classes:
        if doc.format == 'latex':
            text = pf.convert_text(
                pf.Plain(*e.content),
                extra_args=[
                    '--biblatex',
                    '--filter=tools/panflutist/reference_spans.py'
                ],
                input_format='panflute',
                output_format='latex')

            chp = doc.get_metadata('use-chapter', default=False)
            tex = CHAPTER.render(text=text) if chp else SECTION.render(
                text=text)
            return pf.RawBlock(tex, format='latex')
Exemple #25
0
        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)
Exemple #26
0
def block_wrap(elem, orig_elem):
    """Wraps an element in a block if necessary.

    If the original element was block panflute expects the return value to be
    also block. In many places we need to detect this and wrap an inline.

    :param elem: Element to be wrapped
    :type elem: :py:class:`panflute.base.Element`
    :param orig_elem: Original element
    :type orig_elem: :py:class:`panflute.base.Element`

    :rtype: :py:class:`panflute.base.Element`
    :returns: ``elem`` or ``elem`` wrapped in
        :py:class:`panflute.elements.Plain`
    """
    if isinstance(orig_elem, pf.Block):
        return pf.Plain(elem)
    return elem
Exemple #27
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'])
Exemple #28
0
        def repl2(match):
            if match.isspace():  # @  @
                return match

            result = convert.cache.get(match)
            if result is not None:
                return result

            if doc.format == 'latex':
                # Undo `escapeLaTeX` from https://github.com/jgm/skylighting
                match = match.replace('\\textbackslash{}', '\\') \
                             .replace('\\{', '{') \
                             .replace('\\}', '}') \
                             .replace('\\VerbBar{}', '|') \
                             .replace('\\_', '_') \
                             .replace('\\&', '&') \
                             .replace('\\%', '%') \
                             .replace('\\#', '#') \
                             .replace('\\textasciigrave{}', '`') \
                             .replace('\\textquotesingle{}', '\'') \
                             .replace('{-}', '-') \
                             .replace('\\textasciitilde{}', '~') \
                             .replace('\\^{}', '^')

                # Undo the workaround escaping.
                match = match.replace('\\textless{}', '<') \
                             .replace('\\textgreater{}', '>')
            elif doc.format == 'html':
                match = html.unescape(match)

            result = pf.convert_text(
                pf.Plain(*pf.convert_text(match)[0].content).walk(
                    divspan, doc).walk(init_code_elems, doc),
                input_format='panflute',
                output_format=doc.format,
                extra_args=[
                    '--syntax-definition',
                    os.path.join(datadir, 'syntax', 'isocpp.xml')
                ])

            convert.cache[match] = result
            return result
Exemple #29
0
def action(elem, doc):
    if isinstance(elem, pf.Doc):
        version = pkg_resources.get_distribution("panflute").version
        json_serializer = lambda elem: elem.to_json()
        raw = json.dumps(elem, default=json_serializer)
        raw = json.loads(raw)
        raw = json.dumps(raw, check_circular=False,
                         indent=4, separators=(',', ': '))
        disclaimer = pf.Para(pf.Emph(pf.Str('Note: sort order not preserved')))
        elem.content = [
          pf.Header(pf.Str('Python version:'), level=2),
          pf.Para(pf.Str(sys.version)),
          pf.Header(pf.Str('Panflute version:'), level=2),
          pf.Para(pf.Str(version)),
          pf.Header(pf.Str('sys.argv:'), level=2),
          pf.Plain(pf.Str(str(sys.argv))),
          pf.Header(pf.Str('JSON Input:'), level=2),
          disclaimer,
          pf.CodeBlock(raw)
        ]
Exemple #30
0
def build_course_barcode(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))