Exemplo n.º 1
0
def _finalize(doc):
    """_finalize

    :param doc:
    """

    swap_string = "\n".join(
        "  {short!r}: {identifier!r}\n  {long!r}: {identifier!r}".format(
            identifier="+{}_".format(identifier), short=short_, long=long_)
        for identifier, (short_, long_, __) in doc.abbr["definitions"].items())
    logger.debug(
        "Add abbreviations to vale substitutions:\n{}\n".format(swap_string))

    appendix = doc.abbr["appendix"]

    if appendix:
        heading = pf.Header(pf.Str("Abbreviations"),
                            identifier="abbreviations",
                            classes=["unnumbered"])
        doc.content.append(heading)
        appendix.sort(key=lambda x: x[0])
        appendix = map(lambda x: x[1], appendix)
        doc.content.append(pf.DefinitionList(*appendix))

    if "preamble" in doc.metadata:
        existing_preamble = doc.metadata["preamble"].content
    else:
        existing_preamble = []

    doc.metadata["preamble"] = pf.MetaBlocks(
        *existing_preamble,
        *[value for key, value in doc.abbr["latex_preamble"].items()],
    )
Exemplo n.º 2
0
def create_header(
    title_str, doc, level=0, parse_text=False, identifier="", short_title=None
):
    """
    Create a header element.

    Because headers need to be referenced by later elements, references to the
    last found header is remembered.
    """
    if not isinstance(doc, pf.Doc):
        raise ValueError("create_header without Doc element")

    attributes = {}
    if short_title == title_str:
        short_title = None
    if short_title is not None:
        # Attach short title as attribute to be picked up later on by generate_innodoc
        attributes["short_title"] = short_title

    if parse_text:
        title = parse_fragment(title_str, doc.metadata["lang"].text)[0].content
    else:
        title = destringify(title_str)
    header = pf.Header(
        *title, level=level, identifier=identifier, attributes=attributes
    )
    remember(doc, "label", header)
    return header
Exemplo n.º 3
0
def finalize(doc):
    objectives = materialize_unused(doc, all_ids)
    unused_section = pfp.find_by_id('missing-objectives', doc)

    spot = itertools.count(start=unused_section.index + 1)

    for course in sorted(objectives):
        identifier = course.lower().replace(" ", "") + "-missing"
        doc.content.insert(
            next(spot),
            pf.Header(pf.Str(course),
                      level=2,
                      identifier=identifier,
                      classes=["unnumbered"]))
        for header in objectives[course]:
            unit_list = pf.OrderedList()
            for objective in objectives[course][header]:
                if objective.identifier not in referenced_ids:
                    # we've got a handle on the original `pf.Span`, so ask
                    # for its grandparent to get the `pf.ListItem`.
                    unit_list.content.append(objective.ancestor(2))

            # Only put the header into the document *if* the unit actually
            # has learning objectives that were not referenced.
            if len(unit_list.content):
                doc.content.insert(next(spot), header)
                doc.content.insert(next(spot), unit_list)

    # Any appendices (anything *after* the "missing objectives" section) should
    # be unnumbered, because numbering gets difficult after that.
    for elem in doc.content[next(spot):]:
        if isinstance(elem, pf.Header):
            elem.classes.append("unnumbered")
Exemplo n.º 4
0
def action(elem, doc):
    if isinstance(elem, pf.CodeBlock):
        if 'metadata_ref' in elem.classes:
            slugline = make_slugline(elem, doc)
            if slugline:
                return pf.Header(pf.Str(slugline), level=1)
            else:
                return []
    return elem
Exemplo n.º 5
0
def action(elem, doc):
    if isinstance(elem, pf.Para) and is_title_line(elem):
        title = get_title_name(elem)
        chapter_elem = pf.Header(pf.Str(title))
        if elem.content[0].text == '$unnumbered':
            chapter_elem.classes = ['unnumbered']
        return chapter_elem
    elif type(elem) == pf.Header:
        elem.level += 1
Exemplo n.º 6
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
Exemplo n.º 7
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)
        ]
Exemplo n.º 8
0
 def test_handle_mlabel_last_header(self):
     """MTitle command with a last header element"""
     mlabel = pf.RawBlock(r"\MLabel{HEADER}")
     header = pf.Header(pf.Str("headertext"))
     doc = pf.Doc(header, mlabel, format="latex")
     elem = doc.content[0]
     remember(doc, "label", elem)
     ret = self.commands.handle_mlabel(["HEADER"], elem)
     self.assertFalse(ret)
     # pylint: disable=no-member
     self.assertEqual(header.identifier, "HEADER")
Exemplo n.º 9
0
def finalize(doc):
    content = doc.content
    title = doc.get_metadata('title').lower().replace(" ", "") + "-"

    content.append(
        pf.Header(pf.Str(text="Objectives organized by course outcome"),
                  level=1,
                  classes=['unnumbered'],
                  identifier=title + 'organized'))
    for outcome in objectives:
        # turn ":program:" into "Program"
        header = outcome[1:-1].capitalize()
        content.append(
            pf.Header(pf.Str(text=header),
                      level=2,
                      classes=['unlisted', 'unnumbered'],
                      identifier=title + header))
        # the list in the dict is already a bunch of `pf.ListItem`, so just add
        # them in a new `pf.OrderedList`
        content.append(pf.OrderedList(*objectives[outcome]))
Exemplo n.º 10
0
def _finalize(doc):
    # Add headings for the abstracts

    if doc.format != "latex":
        for name in ["abstract", "secondabstract"]:
            abstract = doc.metadata.content.get(name, None)
            abstract_name = doc.get_metadata(f"{name}name", name.capitalize())

            if abstract:
                abstract.walk(mathfilter.role_shortcuts)
                title = pf.Header(pf.Str(abstract_name), level=4)
                doc.metadata[name].content.list.insert(0, title)
Exemplo n.º 11
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"
	})
Exemplo n.º 12
0
    def test_remember(self):
        """It should remember and forget."""
        doc = pf.Doc()

        self.assertIsNone(get_remembered(doc, "somekey"))

        header = pf.Header()
        remember(doc, "header", header)
        rememembered_el = get_remembered(doc, "header")
        self.assertEqual(rememembered_el, header)
        self.assertIsNone(get_remembered(doc, "header"))

        img = pf.Image()
        remember(doc, "img", img)
        rememembered_img = get_remembered(doc, "img")
        self.assertEqual(rememembered_img, img)
        self.assertIsNone(get_remembered(doc, "img"))
Exemplo n.º 13
0
def action(elem, doc):
    if isinstance(elem, pf.Para) and is_include_line(elem):

        fn = get_filename(elem)
        if not os.path.isfile(fn):
            return

        with open(fn) as f:
            raw = f.read()

        new_elems = pf.convert_text(raw)
        new_elems.insert(
            0, pf.Header(pf.Str('=' * 20), pf.Str('Text Box'),
                         pf.Str('=' * 20)))
        new_elems.append(pf.Para(pf.Str('=' * 50)))

        # Alternative A:
        return new_elems
Exemplo n.º 14
0
def finalize(doc):
    has_backmatter = doc.tables or doc.figures
    if has_backmatter:
        pos = doc.backmatter_index  # Already searched by prepare()
        if pos is None:
            raise IndexError(
                'Backmatter not found; add div with identifier "backmatter":\n::: {#backmatter}\n:::\n'
            )
        backmatter = [
            pf.RawBlock(r'\clearpage', format='latex'),
            pf.Header(pf.Str('Figures and Tables'),
                      level=1,
                      identifier='backmatter',
                      classes=['unnumbered'])
        ]
        for figure in doc.figures:
            backmatter.append(figure)
        for table in doc.tables:
            backmatter.append(table)
        doc.content[pos] = pf.Div(*backmatter)
    pass
Exemplo n.º 15
0
def finalize(doc):
    try:
        doc.content.insert(0, pf.Header(pf.Str(doc.title), level=1))
    except:
        return doc
    return doc
Exemplo n.º 16
0
    def convert(self):
        doc = panflute.Doc(
            api_version=(1, 17, 5),
            metadata={
                'pagetitle': self.title,
            },
        )

        doc.content.append(panflute.Header(panflute.Str(self.title)))

        lists = {}
        tables = {}
        table_rows = {}
        table_cells = {}

        for chunk in self._attr_chunks():
            self.logger.debug(chunk)
            container = panflute.Para()
            cdiv = panflute.Div(container)

            # Handle lists
            if 'list_class' in chunk[0]['attrs']:
                lc = chunk[0]['attrs']['list_class']
                check_state = None
                if lc in ['checked', 'unchecked']:
                    check_state = lc
                    lc = 'checklist'
                ld = chunk[0]['attrs']['list_depth']

                # prune any lists that are lower than us, they're finished
                for i in list(lists.keys()):
                    if i > ld:
                        lists.pop(i)

                # non-homogenous list types can be immediately adjacent without
                # ending up merged
                if ld in lists and lists[ld]['class'] != lc:
                    lists.pop(ld)

                # checklists are a special case, they can't contain other lists
                if lc != 'checklist' and lists and lists[1][
                        'class'] == 'checklist':
                    lists = {}

                # make sure any intermediate lists were created, including
                # the top level because boxnotes
                for i in range(1, ld + 1):
                    if i not in lists:
                        lists[i] = self._list(lc, i)
                        if i != ld:
                            lists[i]['pf'].content.append(panflute.ListItem())
                        lp = lists[i]['pf']
                        if lc == 'checklist':
                            lp = panflute.Div(lp, classes=['checklist'])
                        if i == 1:
                            doc.content.append(lp)
                        else:
                            lists[i - 1]['pf'].content[-1].content.append(lp)

                # set the container for the other subchunks
                container = panflute.Plain()
                cdiv.content = [container]
                cdiv.classes.append(lc)
                if check_state:
                    cdiv.classes.append(check_state)
                lists[ld]['pf'].content.append(panflute.ListItem(cdiv))

                if check_state == 'checked':
                    container.content.append(panflute.Str(CHECKED))
                elif check_state == 'unchecked':
                    container.content.append(panflute.Str(UNCHECKED))

            elif 'table_id' in chunk[-1]['attrs']:
                table_id = chunk[-1]['attrs']['table_id']
                row_id = chunk[-1]['attrs']['table_row']
                cell_id = row_id + chunk[-1]['attrs']['table_col']

                if table_id not in tables:
                    # There's some magic in the constructor for panflute tables
                    # that isn't exposed in any other way, so we can't create
                    # the table until we've finished populating the rows.
                    # Instead, use a placeholder div to locate it within the
                    # document.
                    tables[table_id] = {
                        'div': panflute.Div(),
                        'rows': [],
                    }
                    doc.content.append(tables[table_id]['div'])
                if row_id not in table_rows:
                    table_rows[row_id] = panflute.TableRow()
                    tables[table_id]['rows'].append(table_rows[row_id])
                if cell_id not in table_cells:
                    cdiv = panflute.Div(panflute.Plain())
                    table_cells[cell_id] = panflute.TableCell(cdiv)
                    table_rows[row_id].content.append(table_cells[cell_id])
                container = table_cells[cell_id].content[0].content[0]

            else:
                lists = {}
                doc.content.append(cdiv)

            if 'align' in chunk[0]['attrs']:
                cdiv.attributes['style'] = 'text-align: ' + chunk[0]['attrs'][
                    'align'] + ';'

            for subchunk in chunk:
                if subchunk['newlines'] > 1:
                    # we've had an extra linebreak, no more adding on to lists
                    lists = {}

                # don't do anything with markers
                if subchunk['text'] == '*' and 'lmkr' in subchunk['attrs']:
                    continue

                scont = container
                if 'href' in subchunk['attrs']:
                    scont = panflute.Link(url=subchunk['attrs']['href'])
                    container.content.append(scont)

                if 'image' in subchunk['attrs']:
                    scont.content.append(
                        panflute.Image(
                            url=self._image(subchunk['attrs']['author'],
                                            subchunk['attrs']['image'])))
                    continue

                span = panflute.Span()
                lines = subchunk['text'].splitlines()
                while lines:
                    subtext = lines.pop(0)
                    span.content.append(panflute.Str(subtext))
                    if lines:
                        span.content.append(panflute.LineBreak())

                if 'font' in subchunk['attrs']:
                    color = subchunk['attrs']['font'].get('color', '000000')
                    size = subchunk['attrs']['font'].get('size', 'medium')
                    span.classes.append('font-size-' + size)
                    span.classes.append('font-color-' + color)

                    # I don't actually know what the possible colors are and I
                    # don't feel like finding out, so just inject it as an
                    # inline style.
                    if color != '000000':
                        span.attributes['style'] = 'color: #' + color + ';'

                if subchunk['attrs'].get('underline'):
                    span.classes.append('underline')
                if subchunk['attrs'].get('bold'):
                    span = panflute.Strong(span)
                if subchunk['attrs'].get('italic'):
                    span = panflute.Emph(span)
                if subchunk['attrs'].get('strikethrough'):
                    span = panflute.Strikeout(span)
                scont.content.append(span)

        # Actually create the tables
        for x in tables:
            tables[x]['div'].content.append(panflute.Table(*tables[x]['rows']))

        with io.StringIO() as f:
            panflute.dump(doc, f)
            return f.getvalue()
Exemplo n.º 17
0
def finalize(doc):
    header = pf.Header(pf.Str(doc.get_metadata('title')), classes=["unnumbered", "course-title"], level=2)
    doc.content.insert(0, header)
Exemplo n.º 18
0
def finalize(doc):
    ref_section = pf.Header(pf.Str('References'), level=1)
    ref_section.classes.append('unnumbered')
    ref_sub_section = pf.Header(pf.Str('References'), level=2)
    doc.content.append(ref_section)
    doc.content.append(ref_sub_section)
Exemplo n.º 19
0
def plain(elem: Union[panflute.Div, panflute.Header],
          doc: panflute.Doc) -> Optional[panflute.Div]:
    """Assemble the plain text version of the acronym list

    The base plain text output is a bulleted list of acronyms in the
    following format::

        -   {short}: {long}

    in a new :class:`panflute.Div` with the identifier “acronym-list”.
    If the given element is a :class:`panflute.Div`, the list is placed
    under a level 1 header with the text “Acronyms” unless the ``name``
    or ``level`` attributes are set in which case, the request is
    honored.  The list is sorted by the short version of the acronyms by
    default unless the ``sort`` attribute is set to “false” (case
    insensitive) in which case the order is unspecified.  If an
    attribute cannot be interpreted, it is omitted and a warning is
    logged.

    Parameters
    ----------

    elem: :class:`panflute.Div` or :class:`panflute.Header`
        The element to replace
    doc: :class:`panflute.Doc`
        The document under consideration.

    Returns
    -------

    :class:`panflute.Div`, optional:
        The replacement for the block.

    """
    logger = logging.getLogger(__name__ + ".plain_text")
    if "acronyms" not in doc.metadata:
        return None

    if isinstance(elem, panflute.Header):
        header = elem
    elif isinstance(elem, panflute.Div):
        header = panflute.Header(panflute.Str(
            elem.attributes.get("name", "Acronyms")),
                                 level=elem.attributes.get("level", 1))
    else:
        cls = type(elem)
        logger.warning(f"Unknown element type {cls}")
        return None

    if "sort" in elem.attributes:
        sort = elem.attributes["sort"].lower()
        if sort not in ("true", "false"):
            sort = "true"
            logger.warning(f"Unknown 'sort' option '{sort}'")
    else:
        sort = "true"

    if sort == "true":
        acronyms = sorted(doc.acronyms.values(), key=lambda x: x["short"])
    else:
        acronyms = doc.acronyms.values()

    acrolist = [
        panflute.ListItem(
            panflute.Plain(panflute.Strong(panflute.Str(acro["short"])),
                           panflute.Str(":"), panflute.Space,
                           *panflute.convert_text(acro["long"])[0].content))
        for acro in acronyms if acro["list"]
    ]
    return panflute.Div(header,
                        panflute.BulletList(*acrolist),
                        identifier="acronym-list")