def break_newpara(elem, doc):
    if type(elem) == pf.Para:
        splitParas = []
        singleParaElems = []
        needs_to_be_split = False
        for segment in elem.content:
            if isinstance(segment, pf.LineBreak):
                needs_to_be_split = True

        if needs_to_be_split:
            for segment in elem.content:
                if isinstance(segment, pf.LineBreak):
                    splitParas.append(pf.Para(*singleParaElems))
                    singleParaElems = []
                else:
                    singleParaElems.append(segment)
            splitParas.append(pf.Para(*singleParaElems))
            #            pf.debug("Before--------------------")
            #            pf.debug(elem.parent.content)
            #            pf.debug("Before--------------------")
            for i, item in enumerate(splitParas, elem.index + 1):
                elem.parent.content.insert(i, item)


#            pf.debug("Afer--------------------")
#            pf.debug(elem.parent.content)
#            pf.debug("Afer--------------------")
#Delete the original Para
            return []
        else:
            #            pf.debug("no softbreak or linebreak found")
            #            pf.debug(elem)
            return elem
示例#2
0
def action(elem, doc):
    """The panflute filter main method, called once per element."""
    global shift, workaround_level_overflow, workaround_level_underflow
    if isinstance(elem, pf.Header):
        level_old = elem.level
        level_new = level_old + shift
        if level_new > MAX_LEVEL:
            eprint(
                "After shifting header levels by %d, '%s' would be on level %d, "
                "which is above the max level %d." %
                (shift, elem.identifier, level_new, MAX_LEVEL))
            if workaround_level_overflow:
                eprint(
                    "Thus we convert it to an emphazised text paragraph instead."
                )
                if level_new == (MAX_LEVEL + 1):
                    elem = pf.Para(pf.Strong(*elem.content))
                else:
                    elem = pf.Para(pf.Emph(*elem.content))
            else:
                raise OverflowError()
        elif level_new < MIN_LEVEL:
            eprint(
                "After shifting header levels by %d, '%s' would be on level %d, "
                "which is below the min level %d." %
                (shift, elem.identifier, level_new, MIN_LEVEL))
            if workaround_level_underflow:
                eprint("Thus we leave it at the min level.")
            else:
                raise OverflowError()
        else:
            elem.level = level_new
    return elem
示例#3
0
def action(elem, doc):
    if isinstance(elem, panflute.CodeBlock) and 'graphviz' in elem.classes:
        svg = check_output(GRAPHVIZ_COMMAND, input=elem.text.encode('utf8'))
        b64data = b64encode(svg).decode('utf8')
        url = 'data:image/svg+xml;base64,{}'.format(b64data)
        return panflute.Para(panflute.Image(url=url))
    elif isinstance(elem, panflute.CodeBlock) and 'uml' in elem.classes:
        svg = check_output(PLANTUML_COMMAND, input=elem.text.encode('utf8'))
        b64data = b64encode(svg).decode('utf8')
        url = 'data:image/svg+xml;base64,{}'.format(b64data)
        return panflute.Para(panflute.Image(url=url))
示例#4
0
 def test_merge_root_multiple_nodes(self):
     doc = common.MockDoc('html')
     filename = os.path.join('linguafilter', 'test_lexicon.csv')
     attributes = {'file': filename, 'merge_root': 'foo'}
     div = pf.Div(pf.Para(pf.Str('{field1}')),
                  pf.Para(pf.Str('{field2}')),
                  attributes=attributes,
                  classes=['lexicon'])
     with self.assertRaisesRegexp(
             Exception,
             'if merge_root is specified, there can be only one node under the lexicon div'
     ):
         lexicon.parse(div, doc)
示例#5
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))
示例#6
0
def fenced_action(options, data, element, doc):
	modalid  = options.get('id', 'modal1')
	title    = options.get('title')
	closebtn = options.get('closebtn', True)
	size     = options.get('size', 'default')
	size2class = {
		'default': None,
		'small'  : 'modal-sm',
		'sm'     : 'modal-sm',
		'large'  : 'modal-lg',
		'lg'     : 'modal-lg',
		'xlarge' : 'modal-xl',
		'xl'     : 'modal-xl',
	}

	components = []
	if title:
		modal_header1 = pf.Header(pf.Str(title), classes=['modal-title'], level=5, identifier=modalid + 'Title')
		modal_header2 = pf.Div(
			pf.Div(pf.Para(pf.Str('x')), attributes = {'aria-hidden': "true"}),
			classes = ['close', 'button'],
			attributes = {
				'type': 'button',
				'data-dismiss': 'modal',
				'aria-label': 'Close'
			})
		components.append(pf.Div(modal_header1, modal_header2, classes = ['modal-header']))
	components.append(pf.Div(*data, classes = ['modal-body']))
	if closebtn:
		components.append(pf.Div(
			pf.Div(pf.Para(pf.Str('Close')), classes = ['button', 'btn', 'btn-secondary'],
			attributes = {
				'type': 'button',
				'data-dismiss': 'modal',
			}),
			classes = ['modal-footer']
		))
	modal_content = pf.Div(*components, classes = ['modal-content'])
	mainclasses = ['modal-dialog', 'modal-dialog-centered', 'modal-dialog-scrollable']
	sizeclass = size2class.get(size)
	if sizeclass:
		mainclasses.append(sizeclass)
	model_dialog = pf.Div(modal_content, classes = mainclasses, attributes = {'role': 'document'})

	return pf.Div(model_dialog, classes = ['modal', 'fade'], identifier = modalid, attributes = {
		'tabindex'       : '-1',
		'role'           : 'dialog',
		'aria-labelledby': modalid + 'Title',
		'aria-hidden'    : "true"
	})
示例#7
0
 def test_remove_empty_paragraphs(self):
     """It should remove empty paras in document"""
     doc = pf.Doc(
         pf.Para(pf.Str("Foo"), pf.Space(), pf.Str("Bar")),
         pf.Para(),
         pf.Para(pf.Str("Bar"), pf.Space(), pf.Str("Baz")),
     )
     remove_empty_paragraphs(doc)
     self.assertEqual(len(doc.content), 2)
     para1 = doc.content[0]
     self.assertEqual(para1.content[0].text, "Foo")
     self.assertEqual(para1.content[2].text, "Bar")
     para2 = doc.content[1]
     self.assertEqual(para2.content[0].text, "Bar")
     self.assertEqual(para2.content[2].text, "Baz")
示例#8
0
 def test_to_emph_simple(self):
     ast = deepcopy(self.simple)
     ast.walk(self.to_type)
     res = convert_text(ast, input_format="panflute", output_format="native")
     ref = pf.Para(self.ElementType(pf.Str("a")), pf.Space, self.ElementType(pf.Str("b")))
     ref_native = convert_text(ref, input_format="panflute", output_format="native")
     assert res == ref_native
示例#9
0
 def test_unknown_raw_inline_command(self):
     """filter() handles unknown RawInline command"""
     elem_unkown_cmd = pf.RawInline(r"\ThisCommandDoesNotExist",
                                    format="latex")
     para = pf.Para(elem_unkown_cmd)
     ret = self._filter_elem([para], elem_unkown_cmd)
     self.assertIsNone(ret)
示例#10
0
 def test_rawinline(self):
     """filter() handles RawInline element"""
     glqq = pf.RawInline(r"\glqq", format="latex")
     elem = pf.Para(glqq)
     ret = self._filter_elem([elem], glqq)
     self.assertIsInstance(ret, pf.Str)
     self.assertEqual(ret.text, r"„")
示例#11
0
 def test_cancel_emph(self):
     ast = deepcopy(self.ast_double_type)
     ast.walk(self.cancel_repeated_type)
     res = convert_text(ast, input_format="panflute", output_format="native")
     ref = pf.Para(pf.Str("a"), pf.Space, self.ElementType(pf.Str("b")))
     ref_native = convert_text(ref, input_format="panflute", output_format="native")
     assert res == ref_native
示例#12
0
def test_quotes_129():
    #pf https://github.com/sergiocorreia/panflute/issues/129
    text = [pf.Str("Some"), pf.Space, pf.Str("quoted text")]
    quoted_text = pf.Quoted(*text)
    para = pf.Para(quoted_text)
    output = pf.stringify(para, False)
    assert output == '"Some quoted text"'
示例#13
0
 def test_merge_emph2(self):
     ast = deepcopy(self.ast2)
     ast.walk(self.merge_consecutive_type)
     res = convert_text(ast, input_format="panflute", output_format="native")
     ref = pf.Para(self.ElementType(pf.Str("a"), pf.Space, pf.Str("b")))
     ref_native = convert_text(ref, input_format="panflute", output_format="native")
     assert res == ref_native
示例#14
0
 def action(self, elem, doc):
     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
示例#15
0
def is_include_line(elem):
    # value: return 0 for false, 1 for include file, 2 for include header
    value = 0
    config = {}
    name = None
    if not hasattr(elem, "_content"):
        value = 0
    elif (len(elem.content) not in [3, 4]) \
        or (not isinstance(elem.content[0], pf.Str)) \
        or (elem.content[0].text not in ['!include', '$include', '!include-header', '$include-header']) \
        or (not isinstance(elem.content[-2], pf.Space)) \
        or (len(elem.content) == 4 and not isinstance(elem.content[1], pf.Code)):
        value = 0
    else:
        if elem.content[0].text in ['!include', '$include']:
            # include file
            value = 1
        else:
            # include header
            value = 2

        # filename
        fn = elem.content[-1]
        if isinstance(fn, pf.Quoted):
            # Convert list to args of Para
            name = pf.stringify(pf.Para(*fn.content), newlines=False)
        else:
            name = fn.text

        # config
        if len(elem.content) == 4:
            config = parseConfig(elem.content[1].text)

    return value, name, config
示例#16
0
def div2env(elem, doc, debug=False):
    if type(elem) == panflute.Div and doc.format in ["latex", "beamer"]:
        attr = getattr(elem, "attributes", None)
        if not attr:
            return

        env = attr.get("data-environment", "").split(",")
        if not env[0]:
            # This is not marked as an environment
            return

        # Convert the positional arguments to the proper \LaTeX format
        args = attr.get("data-environment-args", "").split(",")
        args = "{{{0}}}".format("}{".join(args)) if args[0] else ""

        # Enclose the keyword arguments in '[...]'
        opt = attr.get("data-environment-keyword", "")
        opt = "[{0}]".format(opt) if opt else ""

        begin = panflute.RawInline(
                "\\begin{{{0}}}{1}{2}%\n".format(env[0], opt, args),
                format="latex"
            )
        end = panflute.RawInline(
                "%\n\\end{{{0}}}".format(env[0]),
                format="latex"
            )
        if debug:
            panflute.debug("begin = '{0!s}'".format(begin))
            panflute.debug("end = '{0!s}'".format(end))

        if not getattr(elem.content[0], "content", False):
            begin = panflute.RawBlock(begin.text, format="latex")
            end = panflute.RawBlock(end.text, format="latex")
            elem = panflute.Div(begin, *elem.content, end)
        else:
            elem.content[0] = panflute.Para(begin,
                                            *elem.content[0].content)
            elem.content[-1] = panflute.Para(*elem.content[-1].content,
                                             end)

        if debug:
            panflute.debug("content = '{0!s}'".format(elem.content))

        return elem

    return
示例#17
0
 def setUp(self):
     self.simple = pf.Para(pf.Str("a"), pf.Space, pf.Str("b"))
     self.ast = pf.Para(self.ElementType(pf.Str("a")), self.ElementType(pf.Str("b")))
     self.ast2 = pf.Para(self.ElementType(pf.Str("a")), pf.Space, self.ElementType(pf.Str("b")))
     self.ast_double_type = pf.Para(
         self.ElementType(self.ElementType(pf.Str("a"))), pf.Space, self.ElementType(pf.Str("b"))
     )
     self.combined = pf.Para(
         self.ElementType(pf.Str("a")),
         self.ElementType(pf.Str("b")),
         pf.Space,
         pf.Str("c"),
         pf.Str("d"),
     )
     self.to_type = partial(to_type, ElementType=self.ElementType)
     self.cancel_repeated_type = partial(cancel_repeated_type, ElementType=self.ElementType)
     self.merge_consecutive_type = partial(merge_consecutive_type, ElementType=self.ElementType)
示例#18
0
 def test_uxid_para(self):
     annot = pf.Div(
         identifier="{}-foo".format(SITE_UXID_PREFIX),
         classes=(SITE_UXID_PREFIX, ),
     )
     para = pf.Para(pf.Str("bar"))
     identifier = extract_identifier([annot, para])
     self.assertEqual(identifier, "foo")
示例#19
0
def finalize(doc):
    reader_options = pf.load_reader_options()
    definitions = []
    for k, v in reader_options.items():
        term = [pf.Str(k)]
        definition = pf.Definition(pf.Para(pf.Str(repr(v))))
        definitions.append(pf.DefinitionItem(term, [definition]))
    doc.content.append(pf.DefinitionList(*definitions))
示例#20
0
def finalize(doc):
    try:
        filepath = doc.get_metadata('filepath')
        label = 'Link'
    except:
        filepath = ''
        label = 'No link'
    doc.content.insert(0, pf.Para(pf.Link(pf.Str(label), url=filepath)))
    return doc
示例#21
0
 def test_handle_mugraphicssolo_inline(self):
     """MUGraphicsSolo command (inline)"""
     content = r"\MUGraphicsSolo{foo.jpg}{width=0.3\linewidth}{}"
     doc = pf.Doc(pf.Para(pf.RawInline(content, format="latex")))
     elem = doc.content[0].content[0]  # this sets up elem.parent
     elem_args = ["foo.jpg", r"width=0.3\linewidth", ""]
     ret = self.commands.handle_mugraphicssolo(elem_args, elem)
     self.assertIsInstance(ret, pf.Image)
     self.assertEqual(ret.url, "foo.jpg")
示例#22
0
def prepare(doc):
    """The panflute filter init method."""
    global doc_path, id_prefix
    doc_path = get_arg(doc, 'll_doc_path')
    id_prefix = linearize_link_path(doc_path)
    # Add reference for the whole file at the top
    if id_prefix != '':
        # empty here, because the id_prefix will be added later in action()
        doc.content.insert(0, pf.Para(pf.RawInline('<a name=""/>')))
示例#23
0
def break_plain(plain):
    """
    Break a Plain element with SoftBreaks into a list of Para elements.
    """
    is_break = lambda el: isinstance(el, pf.SoftBreak)
    content = list(plain.content)

    # group sequences of non-breaks together as paragraphs and throw out breaks
    return [pf.Para(*list(g)) for k, g in groupby(content, is_break) if not k]
示例#24
0
 def test_all_emph_together(self):
     ast = deepcopy(self.combined)
     ast.walk(self.to_type)
     ast.walk(self.cancel_repeated_type)
     ast.walk(self.merge_consecutive_type)
     res = convert_text(ast, input_format="panflute", output_format="native")
     ref = pf.Para(pf.Str("a"), pf.Str("b"), pf.Space, self.ElementType(pf.Str("c"), pf.Str("d")))
     ref_native = convert_text(ref, input_format="panflute", output_format="native")
     assert res == ref_native
示例#25
0
def action(elem, doc):
    if isinstance(elem, pf.Div) and "Question" in elem.classes:
        question = elem
        parent = question.parent
        header = pf.Div(pf.Para(pf.Str("Question {0}".format(doc.latest_question))))
        doc.latest_question += 1
        parent.content[question.index] = header
        header.classes.append("QNumber")
        header.content.append(question)
        return header
示例#26
0
def test_all():
    x=pf.Para(pf.Str("a"))
    y=pf.Para(pf.Str("b"))
    c1=pf.TableCell(x)
    c2=pf.TableCell(y)
    row=pf.TableRow(c1,c2)
    t1 = pf.Table(row)
    t2 = pf.Table(row, header=row)

    print(t1.header)
    print(t2.header)

    with io.StringIO() as f:
        pf.dump(pf.Doc(t1), f)
        print(f.getvalue())

    with io.StringIO() as f:
        pf.dump(pf.Doc(t2), f)
        print(f.getvalue())
示例#27
0
def graphviz_filter(elem, doc):
    if isinstance(elem, pf.CodeBlock) and 'graphviz' in elem.classes:
        code = elem.text
        graph = pygraphviz.AGraph(string=code)
        title = graph.graph_attr.pop('label', '')
        graph.layout()
        path = gen_randpath()
        graph.draw(path, prog='dot')
        para = pf.Para(pf.Image(pf.Str(title), title='fig:', url=path))
        return para
示例#28
0
def finalize(doc: pf.Doc):
    #raise Exception("input file %s header_level %s" % (doc.input_file, doc.header_level))
    header = pf.Header(pf.Str(doc.meta_title), level=doc.header_level)
    doc.content.insert(0, header)
    doc.content.insert(1, pf.Para(pf.Str(doc.description)))
    del doc.header_level
    del doc.input_file
    del doc.meta_title
    del doc.description
    del doc.images_path
    del doc.out_meta
def action(elem, doc):
    if isinstance(elem, pf.Image):
        raw_html = re.search(
            r'<figure>.*?</figure>|<img.*?>',
            pf.convert_text(pf.Para(elem),
                            input_format='panflute',
                            output_format='html',
                            standalone=True,
                            extra_args=['--self-contained']),
            re.DOTALL).group(0).replace('\n', '').replace('\r', '')
        return pf.RawInline(raw_html, format='html')
示例#30
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)
        ]