예제 #1
0
def prepare(doc: Doc) -> Doc:
    from datetime import date
    from itertools import islice, chain, repeat

    def intersperse(delimiter, seq):
        return islice(chain.from_iterable(zip(repeat(delimiter), seq)), 1,
                      None)

    annotate.prepare(doc)

    if "footer" in doc.metadata:
        content = [[Str(str(date.today()))]]
        try:
            old_footer = list(doc.metadata["footer"].content)
        except AttributeError:
            old_footer = [Str("")]

        try:
            version = doc.metadata["version"].content[0]
            content.append([Str("version:"), Space, version])
        except (AttributeError, KeyError):
            pass

        try:
            license = doc.metadata["license"].content[0]
            content.append([Str("license:"), Space, license])
        except (AttributeError, KeyError):
            pass

        content = sum(intersperse([Space, Str("—"), Space], content), [])
        doc.metadata["footer"] = MetaInlines(*old_footer, LineBreak, *content)
예제 #2
0
    def horizontal_card(card_data: JSONType) -> Element:
        assert "title" in card_data and "text" in card_data
        title = card_data["title"]
        text = convert_text(card_data["text"])

        content = []
        body = [
            Header(Str(title), level=3, classes=["card-title"]),
            Div(*text, classes=["card-text"])
        ]

        if "link" in card_data:
            body.append(
                Plain(
                    Link(Str(card_data["link"]["content"]),
                         url=card_data["link"]["href"],
                         classes=["btn", "btn-secondary", "mt-auto", "mx-4"])))

        card_img = Div(Plain(
            Image(url=card_data["image"],
                  title=title,
                  attributes={"width": "100%"})),
                       classes=["col-4"])
        card_body = Div(Div(*body, classes=["card-body"]), classes=["col-8"])
        if card_data["imageLocation"] == "Left":
            content = [card_img, card_body]
        else:
            content = [card_body, card_img]
        content = Div(Div(*content, classes=["row", "no-gutters"]),
                      classes=["card", "rounded-lg"])
        return content
예제 #3
0
def to_html(elem, code):
    div = Div(classes=mapping[code]['classes'])

    # prepare content
    # icon
    icon = Span(classes=mapping[code]['icon-classes'], attributes={'aria-hidden': 'true'})

    # title
    title = [icon, Space]
    if len(elem.content[0].content[1:]) == 0:
        title.append(Str(mapping[code]['title']))
    else:
        title.append(Str(elem.content[0].content[1:]))
    header = Header(*title, level=4, classes=['alert-heading'])

    # title = pf.Strong()
    # title.content = elem.content[0].content[1:]

    # if len(title.content) == 0:
        # title.content.append(pf.Str(' ' + mapping[code]['title']))

    # para = pf.Para(icon, title)

    # div.content.extend(icon)
    div.content.append(header)
    div.content.extend(elem.content[1:])

    return div
예제 #4
0
def replacing(elem, _, search=None, replace=None):
    """
    Function to replace.

    Arguments
    ---------
        elem: element to scan

    Keyword arguments
    -----------------
        search: string to search
        replace: string to replace
    """
    if isinstance(elem, Str):
        search_splitted = elem.text.split(search)
        if len(search_splitted) > 1:

            text = []

            if search_splitted[0] != "":
                text.append(Str(search_splitted[0]))

            for string in search_splitted[1:]:
                text.extend(replace)
                if string != "":
                    text.append(Str(string))

            return text

    return [elem]
예제 #5
0
    def vertical_card(card_data: JSONType) -> Element:
        assert "title" in card_data and "text" in card_data
        title = card_data["title"]
        text = convert_text(card_data["text"])

        content = []
        if "image" in card_data:
            content.append(
                Plain(
                    Image(url=card_data["image"],
                          title=title,
                          classes=["card-img-top"])))

        body = [
            Header(Str(title), level=3, classes=["card-title"]),
            Div(*text, classes=["card-text"])
        ]

        if "link" in card_data:
            body.append(
                Plain(
                    Link(Str(card_data["link"]["content"]),
                         url=card_data["link"]["href"],
                         classes=["btn", "btn-secondary", "mt-auto", "mx-4"])))

        content.append(
            Div(*body, classes=["card-body", "d-flex", "flex-column"]))

        content = Div(Div(*content, classes=["card", "h-100", "rounded-lg"]),
                      classes=["col"])
        return content
예제 #6
0
def replace_local_number(where, local_number):
    """
    Replace local number in where.

    Arguments
    ---------
        where: where to replace
        local_number: replace %n and # by local_number
    """
    where.walk(partial(replacing, search="%n", replace=[Str(local_number)]))
    where.walk(partial(replacing, search="#", replace=[Str(local_number)]))
예제 #7
0
def action(elem, doc):
    if isinstance(elem, CodeBlock):
        name = get_name(elem)
        if name is None:
            return
        if doc.code_count[name] == 0:
            label = Span(Emph(Str(f"«{name}»=")))
            doc.code_count[name] += 1
        else:
            label = Span(Emph(Str(f"«{name}»+")))
        return Div(Para(label), elem, classes=["annotated-code"])
예제 #8
0
def mermaid_to_svg(elem, doc):
    """
    Convert a mermaid snippet to svg
    """
    if isinstance(elem, CodeBlock) and 'mermaid' in elem.classes:
        code = elem.text
        filename = md5(code)
        target = IMAGE_DIR + '/' + filename + '.svg'
        tmpfn = IMAGE_DIR + '/' + filename
        if os.path.isfile(target):
            return Para(
                Image(Str(''),
                      url=target,
                      title='',
                      attributes={'width': '100%'}))
        try:
            os.mkdir(IMAGE_DIR)
            sys.stderr.write('Created directory ' + IMAGE_DIR + '\n')
        except OSError:
            pass

        with open(tmpfn, 'wb') as tmpfn_f:
            tmpfn_f.write(code.encode('utf-8'))

        cmd_line = ['mmdc', '--disable-sandbox', '-i', tmpfn, '-o', target]
        sys.stderr.write("Running %s\n" % " ".join(cmd_line))

        try:
            p = subprocess.Popen(cmd_line,
                                 stdout=subprocess.PIPE,
                                 stdin=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        except OSError:
            raise RuntimeError('command %r cannot be run (needed for mermaid '
                               'output), check the cmd_line setting' %
                               cmd_line)

        stdout, stderr = p.communicate()

        if p.returncode != 0:
            raise RuntimeError('Mermaid exited with error:\n[stderr]\n%s\n'
                               '[stdout]\n%s' % (stderr, stdout))

        if not os.path.isfile(target):
            raise RuntimeError(
                'Mermaid did not produce an output file:\n[stderr]\n%s\n'
                '[stdout]\n%s' % (stderr, stdout))
        sys.stderr.write('Created image ' + target + '\n')
        return Para(
            Image(Str(''), url=target, title='', attributes={'width': '100%'}))
예제 #9
0
def get_header(attrib, suffix):
    if not suffix:
        header_attribute = 'header'
    else:
        header_attribute = SPLIT_DIAGRAM_NAME_FORMAT.format('header', suffix)

    if header_attribute in attrib:
        header_str = attrib[header_attribute]
        if header_str:
            msgs = header_str.split(',', 1)
            if len(msgs) != 2:
                level = 1
                title_str = msgs[0]
            else:
                try:
                    level = int(msgs[0].strip())
                    title_str = msgs[1]
                except:
                    level = 1
                    title_str = msgs[1]

            ident = make_new_ident(re.sub('[ \t\n]', '-', title_str))
            identities.add(ident)

            title = [Str(title_str)]
            header = Header(*title, level=level, identifier=ident)
            return header

    return None
예제 #10
0
def replace_quo_marks(elem, marks):  # pylint: disable=R1710
    """Replace quote nodes with their children flanked by quotation marks.

    :param panflute.Element elem: An element in the AST.
    :param QuoMarks marks: The quotation marks to use.
    :returns: A list with an opening quote (as ``Str``), the children
        of *elem*, and a closing quote (as ``Str``), in that order.
        If *elem* was not quoted, ``None``.
    :rtype: list or None
    """
    if isinstance(elem, Quoted):
        unquoted = list(elem.content)
        if elem.quote_type == 'SingleQuote':
            return [Str(marks.lsquo)] + unquoted + [Str(marks.rsquo)]
        if elem.quote_type == 'DoubleQuote':
            return [Str(marks.ldquo)] + unquoted + [Str(marks.rdquo)]
예제 #11
0
def stylize_inline_pass_dmenu_calls(elem, doc):
    if isinstance(elem, Code) and (
            not is_inside(elem, CodeBlock, DefinitionItem) or
            is_inside(elem, Definition)
            ):
        if elem.text.startswith('pass-dmenu'):
            return Emph(Str(elem.text))
예제 #12
0
def admonition(elem, doc):
    if type(elem) == CodeBlock and (LEVELS & set(elem.classes)):
        level = LEVELS & set(elem.classes)
        code = elem.text
        levelClass = level.pop()
        levelText = Str(EMOJI[levelClass] + " " + levelClass.capitalize())
        content = convert_text(code + REFERENCES)  # re-parse as markdown
        header = LineBlock(LineItem(SmallCaps(levelText)))
        return Div(header, Div(*content), classes="admonition %s" % levelClass)
예제 #13
0
def replace_count(where, count):
    """
    Replace count in where.

    Arguments
    ---------
        where: where to replace
        count: replace %c by count
    """
    where.walk(partial(replacing, search="%c", replace=[Str(count)]))
예제 #14
0
 def references():
     defns = []
     for elem in self.links.values():
         defns.append(
                 DefinitionItem(
                     [de_code(item, Strong) for item in elem.content],
                     [Definition(Para(Str(elem.url)))],
                     ),
                 )
     return DefinitionList(*defns)
예제 #15
0
def filter_keyvalues(kv):
    res = []
    caption = []
    for k, v in kv:
        if k == u"caption":
            caption = [Str(v)]
        else:
            res.append([k, v])

    return caption, "fig:" if caption else "", res
예제 #16
0
def replace_section_number(where, section_number):
    """
    Replace section number in where.

    Arguments
    ---------
        where: where to replace
        section_number: replace %s by section_number
    """
    where.walk(partial(replacing, search="%s", replace=[Str(section_number)]))
예제 #17
0
def replace_global_number(where, global_number):
    """
    Replace global number in where.

    Arguments
    ---------
        where: where to replace
        global_number: replace %g by global_number
    """
    where.walk(partial(replacing, search="%g", replace=[Str(global_number)]))
예제 #18
0
def replace_quo_marks(elem, marks):  # pylint: disable=R1710
    """Replaces quote nodes with their children flanked by quotation marks.

    Arguments:
        ``elem`` (``panflute.Element``):
            An element in the AST.
        ``marks`` (``QuoMarks``):
            The quotation marks to use.

    Returns:
        If ``elem`` was not quoted, nothing.
        Otherwise, a list with an opening quote (as ``Str``), the children
            of ``elem``, and a closing quote (as ``Str``), in that order.
    """
    if isinstance(elem, Quoted):
        unquoted = list(elem.content)
        if elem.quote_type == 'SingleQuote':
            return [Str(marks.lsquo)] + unquoted + [Str(marks.rsquo)]
        elif elem.quote_type == 'DoubleQuote':
            return [Str(marks.ldquo)] + unquoted + [Str(marks.rdquo)]
예제 #19
0
def get_caption_attribute(attrib, suffix):
    if not suffix:
        caption_attribute = 'caption'
    else:
        caption_attribute = SPLIT_DIAGRAM_NAME_FORMAT.format('caption', suffix)

    if caption_attribute in attrib:
        caption_str = attrib[caption_attribute]
        if caption_str:
            return ([Str(caption_str)], 'fig:')

    return ([], '')
예제 #20
0
def action(elem, doc):
    if isinstance(elem, CodeBlock) and "inject" in elem.attributes:
        name = elem.identifier
        label = Emph(Str(f"«{name}»="))
        itemNav = Link(Str(f"{name} output"),
                       url=f"#{name}",
                       classes=["nav-item", "nav-link", "active"],
                       identifier="nav-source-tab",
                       attributes={
                           "data-toggle": "tab",
                           "aria-controls": f"{name}",
                           "aria-selected": "true"
                       })
        sourceNav = Link(label,
                         url="#nav-source",
                         classes=["nav-item", "nav-link"],
                         identifier="nav-source-tab",
                         attributes={
                             "data-toggle": "tab",
                             "aria-controls": "nav-source",
                             "aria-selected": "false"
                         })
        nav = Div(Plain(itemNav, sourceNav),
                  classes=["nav", "nav-tabs"],
                  identifier=f"{name}-nav")

        elem.identifier = f"{name}-source"
        elem.attributes["annotated"] = "true"
        targetPane = Div(classes=["tab-pane", "fade", "show", "active"],
                         identifier=name)
        sourcePane = Div(elem,
                         classes=["tab-pane", "fade"],
                         identifier="nav-source")
        content = Div(targetPane,
                      sourcePane,
                      classes=["tab-content"],
                      identifier=f"{name}-content")
        expanded_source = tangle.get_code(doc.code_map, name)
        script = RawBlock(f"<script>\n{expanded_source}\n</script>")
        return Div(nav, content, script, classes=["entangled-inject"])
예제 #21
0
def metavars(elem, doc):
    if type(elem) == Str:
        m = pattern.match(elem.text)
        if m:
            field = m.group(1)
            result = doc.get_metadata(field, None)

            if type(result) == MetaInlines:
                return Span(*result.content,
                            classes=['interpolated'],
                            attributes={'field': field})
            elif isinstance(result, str):
                return Str(result)
예제 #22
0
def links_to_footnotes(elem, doc):
    """
    Will shift a header level from the filter-header-shift
    metadata value (which must exist)
    """
    if doc.format != 'latex':
        return

    if isinstance(elem, Link):
        if elem.url.startswith('#'):
            return
        if elem.url.startswith('mailto:'):
            return
        if elem.url == stringify(elem):
            return
        return [
            elem,
            Note(
                Para(RawInline(stringify(elem), format='tex'), Str(':'),
                     Space(),
                     Link(Str(elem.url), title=elem.title, url=elem.url)))
        ]
예제 #23
0
    def generate(self):
        credentials = self.get_credentials()
        http = credentials.authorize(httplib2.Http())
        data = None

        if self.config['type'] == 'spreadsheets':
            template = LATEX_JINJA_ENV.get_template('./gdrive-table.tex')
            discoveryUrl = 'https://sheets.googleapis.com/$discovery/rest?version=v4'
            service = discovery.build('sheets',
                                      'v4',
                                      http=http,
                                      discoveryServiceUrl=discoveryUrl)
            result = service.spreadsheets().values().get(
                spreadsheetId=self.config['doc_id'],
                range=self.config['range']).execute()
            data = result.get('values', [])
            output_latex = template.render(data=data, **self.config)
            return RawBlock(text=output_latex, format="latex")

        if self.config['type'] == 'drawings':
            service = discovery.build('drive', 'v3', http=http)
            results = service.files().get(
                fileId=self.config['doc_id'],
                fields='modifiedTime,name').execute()

            request = service.files().export_media(
                fileId=self.config['doc_id'], mimeType='application/pdf')

            file_name = 'gdrive-data/' + self.config['doc_id'] + '.pdf'

            print(request, file=sys.stderr)
            with open(file_name, 'wb') as fh:
                downloader = MediaIoBaseDownload(fh, request)
                done = False
                while done is False:
                    status, done = downloader.next_chunk()
                    print(status, done, file=sys.stderr)
                    print("Download %d%%." % int(status.progress() * 100),
                          file=sys.stderr)

            return Para(
                Image(Str(''),
                      url=file_name,
                      title=self.config.get('title', ''),
                      attributes={'width': '100%'}))

        return data
예제 #24
0
def caps(elem, doc):
    if type(elem) == Str and elem.text == "-subject-":
        data = getJson('data.json')
        subject = data['subject'] + " Frage nummer " + data['question']
        elem.text = subject
        return elem

    if elem.text == "-graph1-":
        caption = "caption"
        src = 'rb_api/output/figures/04.png'
        imgPath = 'rb_api/output/figures/04.png'
        alt = Str(caption)

        if not os.path.isfile(dest):
            return None

        return Image(alt, url=src, title='')
예제 #25
0
파일: metavars.py 프로젝트: garbr0/dgen
def metavars(elem, document):
    for match in PATTERN.finditer(elem.text):
        field = match.group(2)
        result = document.get_metadata(field, None)
        # TODO: dead code. remove after testing
        #if type(result) == MetaInlines:
        #    dgen_utils.log_warn('hitting here. shouldn\'t happen?')
        #    result = Span(*result.content, classes=['interpolated'], attributes={'field': field})
        #    return Span(Str(match.group(1)), result, Str(match.group(3)), classes=['interpolated'])
        #el
        if isinstance(result, unicode):
            return Str(match.group(1) + result + match.group(3))
        dgen_utils.log_warn("metavar not found in document:", field)
    match_bad = PATTERN_BAD.match(elem.text)
    if match_bad:
        dgen_utils.log_warn("found wrong syntax for metavar:",
                            match_bad.group(1))
    return None
예제 #26
0
    def insert_references(self, doc):
        def references():
            defns = []
            for elem in self.links.values():
                defns.append(
                        DefinitionItem(
                            [de_code(item, Strong) for item in elem.content],
                            [Definition(Para(Str(elem.url)))],
                            ),
                        )
            return DefinitionList(*defns)

        for (idx, elem) in enumerate(doc.content):
            if isinstance(elem, Header) and elem.level == 1 and \
                    stringify(elem) == 'COPYRIGHT':
                break
        doc.content.insert(idx, references())
        doc.content.insert(idx, Header(Str('REFERENCES'), level=1))
예제 #27
0
def graphviz(elem, doc):
    if type(elem) == CodeBlock and 'graphviz' in elem.classes:
        code = elem.text
        caption = "caption"
        G = pygraphviz.AGraph(string=code)
        G.layout()
        filename = sha1(code)
        filetype = {'html': 'png', 'latex': 'pdf'}.get(doc.format, 'png')
        alt = Str(caption)
        src = imagedir + '/' + filename + '.' + filetype
        if not os.path.isfile(src):
            try:
                os.mkdir(imagedir)
                sys.stderr.write('Created directory ' + imagedir + '\n')
            except OSError:
                pass
            G.draw(src)
            sys.stderr.write('Created image ' + src + '\n')
        return Para(Image(alt, url=source, title=''))
예제 #28
0
def graphviz(elem, doc):
    """
    Generate a graphviz pdf/png from raw code with a graphviz class
    """
    if isinstance(elem, CodeBlock) and 'graphviz' in elem.classes:
        code = elem.text
        graph = pygraphviz.AGraph(string=code)
        title = graph.graph_attr.pop('label', '')
        # graph.graph_attr.update(margin=0)
        graph.layout()
        filename = md5(code)
        filetype = {'html': 'png', 'latex': 'pdf'}.get(doc.format, 'pdf')
        src = IMAGE_DIR + '/' + filename + '.' + filetype
        if not os.path.isfile(src):
            try:
                os.mkdir(IMAGE_DIR)
                sys.stderr.write('Created directory ' + IMAGE_DIR + '\n')
            except OSError:
                pass
            graph.draw(src, prog='dot')
            sys.stderr.write('Created image ' + src + '\n')
        return Para(Image(Str(''), url=src, title=title, attributes={'width': '100%'}))
예제 #29
0
def plantuml(elem, doc):
    if type(elem) == CodeBlock and 'plantuml' in elem.classes:
        if 'caption' in elem.attributes:
            caption = [Str(elem.attributes['caption'])]
            typef = 'fig:'
        else:
            caption = []
            typef = ''

        filetype = {'html': 'svg', 'latex': 'eps'}.get(doc.format, 'png')
        src = os.path.join(imagedir, filename + '.uml')
        dest = os.path.join(imagedir, filename + '.' + filetype)

        if not os.path.isfile(dest):
            try:
                os.mkdir(imagedir)
                sys.stderr.write('Created directory ' + imagedir + '\n')
            except OSError:
                pass

            txt = code.encode("utf-8")
            if not txt.startswith("@start"):
                txt = "@startuml\n" + txt + "\n@enduml\n"
            with open(src, "w") as f:
                f.write(txt)

            call(["java", "-jar", "plantuml.jar", "-t" + filetype, src])

            sys.stderr.write('Created image ' + dest + '\n')

        return Para(
            Image(*caption,
                  identifier=elem.identifier,
                  attributes=elem.attributes,
                  url=dest,
                  title=typef))
예제 #30
0
def caps(elem, doc):
    data = getJson('data.json')
    if isinstance(elem, pf.RawBlock) and (elem.format == 'html'):
        if elem.text == "<!-- feedback -->":
            feedback = data[data['subject']+str(data['questionNumber'])]
            body = []
            i=0
            for item in feedback:
                cells = [str(i+1),item]
                cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells]
                row = pf.TableRow(*cells)
            
                body.append(pf.TableBody(row))
                i=i+1

            cells = ['Nr.','Empfehlung']
            cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells]
            row = pf.TableRow(*cells)
            head = pf.TableHead(row)

            width = [0.1,0.7]
            alignment = ['AlignDefault'] * len(width)
            caption = 'Empfehlungen'
            caption = pf.Caption(Para(Str(caption)))
            return pf.Div(pf.Table(*body, colspec=zip(alignment, width), caption=caption))
        
        if elem.text == "<!-- textelementen -->":
            subject = data[data['subject']+str(data['questionNumber'])+'_cna']
            body = []
            i=0
            for item in subject:
                cells = [item[0], item[1]]
                cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells]
                row = pf.TableRow(*cells)
            
                body.append(pf.TableBody(row))
                i=i+1

            cells = ['Abschnitt','Schlusselwörter']
            cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells]
            row = pf.TableRow(*cells)
            head = pf.TableHead(row)

            width = [0.16,0.7]
            alignment = ['AlignDefault'] * len(width)
            caption = 'Textelementen'
            caption = pf.Caption(Para(Str(caption)))
            return pf.Div(pf.Table(*body, colspec=zip(alignment, width), caption=caption))

        if elem.text == "<!-- unterschied -->":
            expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword']
            student = data[data['subject']+str(data['questionNumber'])+'_keyword']
            sorted_expert = sorted(expert, key = lambda k:k['degree'])
            sorted_student = sorted(student, key = lambda k:k['degree'])
            unterschied = []
            for e in expert:
                unterschied.append(e["displayName"]+"("+str(round(float(e["degree"])*100, 2))+")")
                
            for e in expert:
                inside = True
                for s in student:
                    if e['displayName'] == s['displayName']:
                        inside= False
                        break
                if not inside:
                    unterschied.append(e["displayName"]+"("+str(round(float(e["degree"])*100, 2))+")")
                
                break
            string =''
            if len(unterschied) == 1:
                string+= str(unterschied[0])
            elif len(unterschied)>1:
                string = unterschied[0]
                for index in range(1, len(unterschied)-1): 
                    string +=', '+ str(unterschied[index])

            body = []
            
            cells = [string]
            cells = [pf.TableCell(pf.Plain(Str(cell))) for cell in cells]
            row = pf.TableRow(*cells)
        
            body.append(pf.TableBody(row))
                

            

            width = [0.8]
            alignment = ['AlignDefault'] * len(width)
            caption = 'Textelementen'
            caption = pf.Caption(Para(Str(caption)))
            return pf.Div(pf.Table(*body, colspec=zip(alignment, width), caption=caption))


        if elem.text == "- gemeinsam -":
            expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword']
            student = data[data['subject']+str(data['questionNumber'])+'_keyword']
            sorted_expert = sorted(expert, key = lambda k:k['degree'])
            sorted_student = sorted(student, key = lambda k:k['degree'])
            gemeinsam = []
            for e in expert:
                for s in student:
                    if e['displayName'] == s['displayName']:
                        gemeinsam.append(e["displayName"]+"("+str(round(float(e["degree"])*100, 2))+")")
                    break
                else:
                    continue
                break
            string =''
            gemeinsam = [x["displayName"]+"("+str(round(float(x["degree"])*100, 2))+")" for x in expert+student if (any(e['displayName'])==x['displayName'] for e in  expert) and (any(s['displayName'])==x['displayName'] for s in student)]
            if len(gemeinsam) == 1:
                string+= gemeinsam[0]
            elif len(gemeinsam)>1:
                string = gemeinsam[0]
                for index in range(1, len(gemeinsam)-1): 
                    string +=', '+ gemeinsam[index]

            return string

    if type(elem) == Str: 
        if elem.text == "-topicName-":
            subject = data['subject'] +" Frage nummer " + str(data['questionNumber'])
            elem.text = subject
            return elem
        
        if elem.text == "-textelementen-":
            subject = data[data['subject']+str(data['questionNumber'])+'_cna']
            subject = subject.replace("_", " ")
            elem.text = subject
            return elem
        
        if elem.text == "-question_number-":
            feedback = str(data['questionNumber'])
            elem.text = feedback
            return elem

        if elem.text == "-gemeinsam-":
            expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword']
            student = data[data['subject']+str(data['questionNumber'])+'_keyword']
            sorted_expert = reversed(sorted(expert, key = lambda k:k['degree']))
            sorted_student = reversed(sorted(student, key = lambda k:k['degree']))
            
            string =''
            list_of_all_values = [value for elem in sorted_student
                      for value in elem.values()]
            gemeinsam = [x["displayName"] for x in sorted_expert if x['displayName'] in list_of_all_values]
            if len(gemeinsam) == 1:
                string+= gemeinsam[0]
            elif len(gemeinsam)>1:
                string = gemeinsam[0]
                for index in range(1, len(gemeinsam)-1): 
                    string +=', '+ gemeinsam[index]
            elem.text = string
            return elem

        if elem.text == "-unterschied1-":
            expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword']
            student = data[data['subject']+str(data['questionNumber'])+'_keyword']
            sorted_expert = reversed(sorted(expert, key = lambda k:k['degree']))
            sorted_student = reversed(sorted(student, key = lambda k:k['degree']))
            
            string =''
            list_of_all_values = [value for elem in sorted_student
                      for value in elem.values()]
            gemeinsam = [x["displayName"] for x in sorted_expert if x['displayName'] not in list_of_all_values]
            if len(gemeinsam) == 1:
                string+= gemeinsam[0]
            elif len(gemeinsam)>1:
                string = gemeinsam[0]
                for index in range(1, len(gemeinsam)-1): 
                    string +=', '+ gemeinsam[index]
            elem.text = string
            return elem

        if elem.text == "-unterschied2-":
            expert = data[data['subject']+str(data['questionNumber'])+'_expert_keyword']
            student = data[data['subject']+str(data['questionNumber'])+'_keyword']
            sorted_expert = reversed(sorted(expert, key = lambda k:k['degree']))
            sorted_student = reversed(sorted(student, key = lambda k:k['degree']))
            
            string =''
            list_of_all_values = [value for elem in sorted_expert
                      for value in elem.values()]
            gemeinsam = [x["displayName"] for x in sorted_student if x['displayName'] not in list_of_all_values]
            if len(gemeinsam) == 1:
                string+= gemeinsam[0]
            elif len(gemeinsam)>1:
                string = gemeinsam[0]
                for index in range(1, len(gemeinsam)-1): 
                    string +=', '+ gemeinsam[index]
            elem.text = string
            return elem

        if elem.text == "-expert-":
            caption = "caption"
            src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_expert_keyword.png'
            alt = Str(caption)

            if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_expert_keyword.png'):
                return None

            return Image(alt, url=src, title='')

        if elem.text == "-student-":
            caption = "caption"
            src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_keyword.png'
            alt = Str(caption)

            if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_keyword.png'):
                return None

            return Image(alt, url=src, title='')

        if elem.text == "-content-":
            caption = "caption"
            src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_content.png'
            alt = Str(caption)

            if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_content.png'):
                return None

            return Image(alt, url=src, title='')
        
        if elem.text == "-heat-":
            caption = "caption"
            src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_content_heat.png'
            alt = Str(caption)

            if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_content_heat.png'):
                return None

            return Image(alt, url=src, title='')
        
        if elem.text == "-topic-":
            caption = "caption"
            src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_topic.png'
            alt = Str(caption)

            if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_topic.png'):
                return None

            return Image(alt, url=src, title='')

        if elem.text == "-argument-":
            caption = "caption"
            src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_argument.png'
            alt = Str(caption)

            if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_argument.png'):
                return None

            return Image(alt, url=src, title='')
        
        if elem.text == "-wordtovec-":
            caption = "caption"
            src = 'rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_word2vec.png'
            alt = Str(caption)

            if not os.path.isfile('rb_api/pandoc_filters/images/'+data['subject']+str(data['questionNumber'])+'_cna_word2vec.png'):
                return None

            return Image(alt, url=src, title='')