def reformat_spaced_repetition_text(key, value, format, meta):
    if key == 'Para':
        # the spaced repetition text will always start with 'Q:'
        first_word = value[0]['c']
        if first_word == 'Q:':
            # the content of a paragraph is a list of inline elements
            # e.g. links, line breaks, in-line code snippets, text
            started_parsing_answer: bool = False

            para_question = []
            para_answer = []

            for inline in value:
                # there's always a soft line break before the 'A:'
                # once we've seen the soft break, we want to start populating
                # the list containing the inlines that make up the answer
                if inline['t'] == 'SoftBreak':
                    started_parsing_answer = True

                if started_parsing_answer:
                    para_answer.append(inline)
                else:
                    para_question.append(inline)

            # see constructor doc: https://github.com/jgm/pandocfilters/blob/master/pandocfilters.py
            return [
                Div(attributes({'class': 'question'}), [Plain(para_question)]),
                Div(attributes({'class': 'answer'}), [Plain(para_answer)])
            ]
def pygments(key, value, format, _):

    if format == "asciidoc":

        # Fix references to figures
        if (key == "Str") and value.startswith("@ref"):
            # stderr.write(f"{key}\t{value}\n")
            _, ref_type, ref_id, _ = re.split("\(|:|\)", value)
            return Str(f"<<{ref_type}:{ref_id}>>")

        elif key == "Div":
            [[ident, classes, keyvals], code] = value
            div_type = classes[0]

            # Fix admonition
            if div_type.startswith("rmd"):
                adm_type = div_type[3:]
                return Plain([Str(f"[{ADM_TYPE[adm_type]}]\n====\n")] +
                             code[0]["c"] + [Str("\n====\n\n")])

            # Fix figures
            elif div_type == "figure":
                fig_id = code[2]["c"][0]["c"].split(")")[0][2:]
                html = code[0]["c"][0]["c"][1]
                stderr.write(f"{html}\n")
                _, src, _, alt, *_ = html.split("\"")
                return Plain(
                    [Str(f"[[{fig_id}]]\n.{alt}\nimage::{src}[{alt}]")])

    elif format == "html4":

        # Turn text callout number into unicode char
        if (key == "Str") and (match := callout_text_re.fullmatch(value)):
            num = int(match.group(1))
            br = "<br>" if num > 1 else ""
            return RawInline(
                "html", f"{br}<span class=\"callout\">&#{num + 10121};</span>")

        # Insert "Figure" or "Example" in front of internal references
        if (key == "Str") and value.startswith("@ref"):
            _, ref_type, ref_id, _ = re.split("\(|:|\)", value)
            return Str(f"{REF_TYPE[ref_type]} {value}")

        elif key == "CodeBlock":
            [[ident, classes, keyvals], code] = value
            if classes:
                language = classes[0]
                # stderr.write(f"{key}\t{value}\t{format}\n")
                result = "<pre>" + conv.convert(code, full=False) + "</pre>"

                # Turn code callout number into unicode char
                result = callout_code_re.sub(
                    lambda x:
                    f"<span class=\"callout\">&#{int(x.group(1))+10121};</span>",
                    result)
            else:
                result = code
            return RawBlock("html", result)
Exemple #3
0
def pygments(key, value, format, _):

    # if key not in ["Space", "Str", "RawInline", "Para", "Quoted", "Plain"]:
    # stderr.write(f"- {key}: {value[:100]}\n")

    # if (key == "Str") and "fig:" in value:
    #     stderr.write(f"{key}\t{value}\t{format}\n")

    if format == "asciidoc":

        # Fix references to figures
        if (key == "Str") and value.startswith("@ref"):
            # stderr.write(f"{key}\t{value}\n")
            _, ref_type, ref_id, _ = split("\(|:|\)", value)
            return Str(f"<<{ref_type}:{ref_id}>>")

        elif key == "Div":
            [[ident, classes, keyvals], code] = value
            div_type = classes[0]

            # Fix admonition
            if div_type.startswith("rmd"):
                adm_type = div_type[3:]
                return Plain([Str(f"[{ADM_TYPE[adm_type]}]\n====\n")] +
                             code[0]["c"] + [Str("\n====\n\n")])

            # Fix figures
            elif div_type == "figure":
                fig_id = code[2]["c"][0]["c"].split(")")[0][2:]
                html = code[0]["c"][0]["c"][1]
                _, src, _, alt, _ = html.split("\"")
                return Plain(
                    [Str(f"[[{fig_id}]]\n.{alt}\nimage::{src}[{alt}]")])

    elif format == "html4":

        # Insert "Figure" or "Example" in front of internal references
        if (key == "Str") and value.startswith("@ref"):
            _, ref_type, ref_id, _ = split("\(|:|\)", value)
            return Str(f"{REF_TYPE[ref_type]} {value}")

        # Highlight code using pygments
        elif key == "CodeBlock":
            [[ident, classes, keyvals], code] = value
            language = classes[0]
            # stderr.write(f"\n\nformat: {format}\n\n```" + language + "\n" + code + "\n```\n\n\n")
            result = highlight(code, get_lexer_by_name(language),
                               HtmlFormatter())
            return RawBlock("html", result)
def handleCodeBlock(value):
    t = "code"
    if value[0][0]:
        t = value[0][0]
    r = []
    ## debut hack
    if t == "header":  # title, author, date
        return getTitleAuthorDate(value[1])
    elif t == "keywords":
        return getKeywords(value[1])
    ## fin hack
    linenbr = 0
    for s in value[1].split('\n'):
        linenbr = linenbr + 1
        rb1 = RawBlock('html', '<text:p text:style-name="' + t + '">')
        r.append(rb1)
        # add line number for code blocks only
        if t == "code":
            linenbrstr = "{:02d}".format(linenbr)
            i = 0
            #while i < len(linenbrstr) and linenbrstr[i] == " ":
            ##lnlspaces = len(linenbrstr) - len(linenbrstr.lstrip(' '))
            ##if lnlspaces > 0:
            #    r.append(RawBlock('html', '<text:s/>'))
            #    i += 1
            r.append(RawBlock('html', linenbrstr))
        # count number of space characters at the beginning of the line
        lspaces = len(s) - len(s.lstrip(' '))
        if lspaces > 0:
            r.append(
                RawBlock('html', '<text:s text:c="' + str(lspaces) + '"/>'))
        r.append(Plain([Str(s)]))
        rb2 = RawBlock('html', '</text:p>')
        r.append(rb2)
    return r
Exemple #5
0
def replaceCodelistingForLstlisting(token):
    begin_token = RawBlock('latex', '\\begin{codelisting}')
    end_token = RawBlock('latex', '\\end{codelisting}')

    if (begin_token, end_token) != (token[1][0], token[1][3]):
        return token

    ret = [token[0], [Plain([])]]  # a content of `Div` token

    # set begin command
    line = '\\begin{lstlisting}['
    params = extractParameters(token[1][2])
    params_strings = [
        "{}={}".format(key, item) for key, item in params.items()
    ]
    ret[1][0]['c'].append(
        RawInline('latex', line + ",".join(params_strings) + "]\n"))

    # set the source code
    for line in token[1][2]['c'][1].split('\n'):
        ret[1][0]['c'].append(RawInline('latex', line + "\n"))

    # set end command
    ret[1][0]['c'].append(RawInline('latex', '\\end{lstlisting}'))

    return Div(*ret)
Exemple #6
0
def replace_attrtables(key, value, fmt, meta):
    """Replaces attributed tables while storing reference labels."""

    if is_attrtable(key, value):

        # Parse the table
        content, caption, label = parse_attrtable(value)

        # Bail out if the label does not conform
        if not label or not LABEL_PATTERN.match(label):
            return None

        # Save the reference
        references[label] = len(references) + 1

        # Adjust caption depending on the output format
        if fmt == 'latex':
            caption = list(caption) + [RawInline('tex', r'\label{%s}' % label)]
        else:
            caption = ast('Table %d. ' % references[label]) + list(caption)

        # Return the replacement
        # pylint: disable=star-args
        args = [
            caption,
        ] + content
        if fmt in ('html', 'html5'):
            anchor = RawInline('html', '<a name="%s"></a>' % label)
            return [Plain([anchor]), Table(*args)]
        else:
            return Table(*args)
def listing(key, value, format, meta):
    #eprint("Key: " + key)
    if key == 'CodeBlock':
        (caption, _) = get_value(value[0][2], 'caption')

        if caption is None:
            return

        block = CodeBlock(value[0], value[1])

        # we only need to add the caption, label is handled by Pandoc
        return \
            [ Plain([latex(r'\begin{listing}' + '\n' + \
                           r'\caption{' + caption + '}')]) \
            , block \
            , Plain([latex(r'\end{listing}')]) \
            ]
def makePlainFromParaValues(values):
    newv = []
    t = values[0]['t']
    if t == 'Image':
        for v in values:
            newv.append(v)
        p = Plain(newv)
        return p

    rb1 = RawInline('html', '<text:p text:style-name="Normal">')
    newv.append(rb1)
    for v in values:
        myvals = handleParagraphValue(v)
        for myv in myvals:
            newv.append(myv)
    rb2 = RawInline('html', '</text:p>')
    newv.append(rb2)
    p = Plain(newv)
    return p
Exemple #9
0
def preprocess(key, value, fmt, meta):
    """Preprocesses to correct for problems."""
    if key in ('Para', 'Plain'):
        while True:
            newvalue = repair_broken_refs(value)
            if newvalue:
                value = newvalue
            else:
                break
        if key == 'Para':
            return Para(value)
        else:
            return Plain(value)
def handleHeaders(value):
    depth = value[0]
    text = value[1][0]
    if depth >= 1 and depth <= 3:
        r = []
        r.append(
            RawBlock(
                'html',
                '<text:h text:style-name="Heading_20_1" text:outline-level="' +
                str(depth) + '">' + getHeaderNumber(depth)))
        r.append(Plain(value[2]))
        r.append(RawBlock('html', '</text:h>'))
        return r
    else:
        raise Exception("unknown header depth: ", depth)
Exemple #11
0
def preffyify_fractions(key, value, format, meta):
    if key == 'Plain':
        modified_value = value[:]
        for tidx, token in enumerate(modified_value):
            if token['t'] != 'Str':
                continue

            content = token['c']
            split = re.split(r'(\d+/\d+)', content)
            if len(split) > 1:
                for idx, part in enumerate(split):
                    if idx % 2:
                        split[idx] = fractionalize(part)

                token['c'] = ''.join(split)

        return Plain(modified_value)
Exemple #12
0
def pandocfilter(key, value, xformat, meta):
    '''
    {"t":"RawInline","c":["latex","\\index[general]{Command!bconsole}"]}]}
    '''
    logger = logging.getLogger()
    if key == "RawInline" or key == 'RawBlock':
        logger.debug('value {}'.format(value))
        logger.debug('format {}'.format(xformat))
        logger.debug('meta {}'.format(meta))
        result = parseAndTranslate(value[1])
        logger.debug('result: {}'.format(result))
        if key == "RawInline":
            return Str(result)
            #return Code(None, result)
            #return Code(('', [], []), result)
        elif key == 'RawBlock':
            return Plain([Str(result)])
    return None
Exemple #13
0
    def __call__(
            self, key: str, value: Any, output_format: str, meta: str) -> Any:
        """Process JSON elements.

        For each key, this method calls a method "process_key" (with a lower
        case key). Therefore it dispatches the action calls to appropriate
        methods. If there is no such method, nothing is changed.
        """
        # print(key, output_format, repr(value), file=sys.stderr)
        action = getattr(self, 'process_' + key.lower(), None)
        if action is None:
            # print(key, output_format, repr(value), file=sys.stderr)
            return None
        try:
            return action(value, output_format, meta)
        except Exception as exc:  # pylint: disable=broad-except
            print(traceback.format_exc(), file=sys.stderr)
            return Plain([Strong([Str("Filter error: " + str(exc))])])
Exemple #14
0
def replace_refs(key, value, fmt, meta):
    """Replaces references to labelled images."""

    # Remove braces around references
    if key in ('Para', 'Plain'):
        if remove_braces(value):
            if key == 'Para':
                return Para(value)
            else:
                return Plain(value)

    # Replace references
    if is_ref(key, value):
        prefix, label, suffix = parse_ref(value)
        # The replacement depends on the output format
        if fmt == 'latex':
            return prefix + [RawInline('tex', r'\ref{%s}' % label)] + suffix
        elif fmt in ('html', 'html5'):
            link = '<a href="#%s">%s</a>' % (label, references[label])
            return prefix + [RawInline('html', link)] + suffix
        else:
            return prefix + [Str('%d' % references[label])] + suffix
Exemple #15
0
def replace_attrimages(key, value, fmt, meta):
    """Replaces attributed images while storing reference labels."""

    if is_attrimage(key, value):

        # Parse the image
        attrs, caption, target, label = parse_attrimage(value)

        # Bail out if the label does not conform
        if not label or not LABEL_PATTERN.match(label):
            return None

        # Save the reference
        references[label] = len(references) + 1

        # Adjust caption depending on the output format
        if fmt == 'latex':
            caption = list(caption) + [RawInline('tex', r'\label{%s}' % label)]
        else:
            caption = ast('Figure %d. ' % references[label]) + list(caption)

        # Required for pandoc to process the image
        target[1] = "fig:"

        # Return the replacement
        if len(value[0]['c']) == 2:  # Old pandoc < 1.16
            img = Image(caption, target)
        else:  # New pandoc >= 1.16
            assert len(value[0]['c']) == 3
            img = AttrImage(attrs, caption, target)

        if fmt in ('html', 'html5'):
            anchor = RawInline('html', '<a name="%s"></a>' % label)
            return [Plain([anchor]), Para([img])]
        else:
            return Para([img])
Exemple #16
0
def listof(key, value, format, meta):
    global headers2

    # Is it a header?
    if key == 'Header':
        [level, [id, classes, attributes], content] = value
        if 'unnumbered' not in classes:
            headers2[level - 1] = headers2[level - 1] + 1
            for index in range(level, 6):
                headers2[index] = 0

    # Is it a paragraph with only one string?
    if key == 'Para' and len(value) == 1 and value[0]['t'] == 'Str':

        # Is it {tag}?
        result = re.match('^{(?P<name>(?P<prefix>[a-zA-Z][\w.-]*)(?P<section>\:((?P<sharp>#(\.#)*)|(\d+(\.\d+)*)))?)}$', value[0]['c'])
        if result:

            prefix = result.group('prefix')

            # Get the collection name
            if result.group('sharp') == None:
                name = result.group('name')
            else:
                level = (len(result.group('sharp')) - 1) // 2 + 1
                name = prefix + ':' + '.'.join(map(str, headers2[:level]))

            # Is it an existing collection
            if name in collections:

                if format == 'latex':
                    # Special case for LaTeX output
                    if 'toccolor' in meta:
                        linkcolor = '\\hypersetup{linkcolor=' + stringify(meta['toccolor']['c'], format) + '}'
                    else:
                        linkcolor = '\\hypersetup{linkcolor=black}'
                    if result.group('sharp') == None:
                        suffix = ''
                    else:
                        suffix = '_'
                    return Para([RawInline('tex', linkcolor + '\\makeatletter\\@starttoc{' + name + suffix + '}\\makeatother')])

                else:
                    # Prepare the list
                    elements = []

                    # Loop on the collection
                    for value in collections[name]:

                        # Add an item to the list
                        if pandocVersion() < '1.16':
                            # pandoc 1.15
                            link = Link([Str(value['text'])], ['#' + prefix + ':' + value['identifier'], ''])
                        else:
                            # pandoc 1.16
                            link = Link(['', [], []], [Str(value['text'])], ['#' + prefix + ':' + value['identifier'], ''])

                        elements.append([Plain([link])])

                    # Return a bullet list
                    return BulletList(elements)

        # Special case where the paragraph start with '{{...'
        elif re.match('^{{[a-zA-Z][\w.-]*}$', value[0]['c']):
            value[0]['c'] = value[0]['c'][1:]
def handle_comments(key, value, docFormat, meta):
    global INLINE_TAG_STACK, BLOCK_COMMENT, INLINE_COMMENT, INLINE_MARGIN,\
        INLINE_HIGHLIGHT, INLINE_FONT_COLOR_STACK

    # If translating to markdown, leave everything alone.
    if docFormat == 'markdown':
        return

    # Get draft status from metadata field (or assume not draft if there's
    # no such field)
    try:
        draft = meta['draft']['c']
    except KeyError:
        draft = False

    # Check to see if we're starting or closing a Block element
    if key == 'RawBlock':
        elementFormat, tag = value
        if elementFormat != 'html':
            return
        tag = tag.lower()

        if not draft:
            if BLOCK_COMMENT:  # Need to suppress output
                if tag == '</!comment>':
                    BLOCK_COMMENT = False
                return []

        # Not currently suppressing output ...

        if tag in ['<!comment>', '<!box>', '<center>', '<!speaker>']:
            if tag == '<!comment>':
                BLOCK_COMMENT = True
                if not draft:
                    return []
                INLINE_FONT_COLOR_STACK.append(COLORS[tag])
            if docFormat == 'latex':
                return Para([latex(LATEX_TEXT[tag])])
                # FIXME: What about beamer?
            elif docFormat in ['html', 'html5']:
                return Plain([html(HTML_TEXT[tag])])
            elif docFormat == 'revealjs':
                return Plain([html(REVEALJS_TEXT[tag])])
            else:
                return
        elif tag in ['</!comment>', '</!box>', '</center>', '</!speaker>']:
            if INLINE_TAG_STACK:
                debug(
                    'Need to close all inline elements before closing block elements!\n\n{}\n\nbefore\n\n{}\n\n'
                    .format(str(INLINE_TAG_STACK), tag))
                exit(1)
            if tag == '</!comment>':
                BLOCK_COMMENT = False
                if not draft:
                    return []
                INLINE_FONT_COLOR_STACK.pop()
            if docFormat == 'latex':
                return Para([latex(LATEX_TEXT[tag])])
                # FIXME: What about beamer?
            elif docFormat in ['html', 'html5']:
                return Plain([html(HTML_TEXT[tag])])
            elif docFormat == 'revealjs':
                return Plain([html(REVEALJS_TEXT[tag])])
            else:
                return
        else:
            return  # TODO Is this the right thing to do?

    if not draft and BLOCK_COMMENT:
        return []  # Need to suppress output

    # Then check to see if we're changing INLINE_TAG_STACK...
    elif key == 'RawInline':
        elementFormat, tag = value
        if elementFormat != 'html':
            return

        # Check to see if need to suppress output. We do this only for
        # `<comment>` and `<margin>` tags; with `<fixme>` and `<highlight>`
        # tags, we merely suppress the tag.
        if not draft:
            if tag == '<comment>':
                INLINE_COMMENT = True
                return []
            elif tag == '<margin>':
                INLINE_MARGIN = True
                return []
            elif INLINE_COMMENT:  # Need to suppress output
                if tag == '</comment>':
                    INLINE_COMMENT = False
                return []
            elif INLINE_MARGIN:  # Need to suppress output
                if tag == '</margin>':
                    INLINE_MARGIN = False
                return []
            elif tag in ['<fixme>', '<highlight>', '</fixme>', '</highlight>']:
                return []  # Suppress the tag (but not the subsequent text)

        # Not currently suppressing output....

        if tag in [
                '<comment>', '<fixme>', '<margin>', '<highlight>',
                '</comment>', '</fixme>', '</margin>', '</highlight>'
        ]:
            # LaTeX gets treated differently than HTML
            if docFormat in ['latex', 'beamer']:
                preText = ''
                postText = ''
                # Cannot change COLORS within highlighting in LaTeX (but
                # don't do anything when closing the highlight tag!)
                if INLINE_HIGHLIGHT and tag != '</highlight>':
                    preText = LATEX_TEXT['</highlight>']
                    postText = LATEX_TEXT['<highlight>']
                if tag in ['<comment>', '<fixme>', '<margin>',
                           '<highlight>']:  # If any opening tag
                    if tag == '<comment>':
                        INLINE_COMMENT = True
                        INLINE_FONT_COLOR_STACK.append(COLORS[tag])
                    elif tag == '<fixme>':
                        INLINE_FONT_COLOR_STACK.append(COLORS[tag])
                    elif tag == '<margin>':
                        INLINE_MARGIN = True
                        INLINE_FONT_COLOR_STACK.append(COLORS[tag])
                    elif tag == '<highlight>':
                        INLINE_HIGHLIGHT = True
                        INLINE_FONT_COLOR_STACK.append(
                            INLINE_FONT_COLOR_STACK[-1])
                    INLINE_TAG_STACK.append(tag)
                    return latex(preText + LATEX_TEXT[tag] + postText)
                elif tag in [
                        '</comment>', '</fixme>', '</margin>', '</highlight>'
                ]:
                    if tag == '</comment>':
                        INLINE_COMMENT = False
                    elif tag == '</fixme>':
                        pass
                    elif tag == '</margin>':
                        INLINE_MARGIN = False
                    elif tag == '</highlight>':
                        INLINE_HIGHLIGHT = False
                    INLINE_FONT_COLOR_STACK.pop()
                    previousColor = INLINE_FONT_COLOR_STACK[-1]
                    currentInlineStatus = INLINE_TAG_STACK.pop()
                    if currentInlineStatus[1:] == tag[2:]:
                        # matching opening tag
                        return latex('{}{}\\color{{{}}}{{}}{}'.format(
                            preText, LATEX_TEXT[tag], previousColor, postText))
                    else:
                        debug(
                            'Closing tag ({}) does not match opening tag ({}).\n\n'
                            .format(tag, currentInlineStatus))
                        exit(1)
            else:  # Some docFormat other than LaTeX/beamer
                if tag in ['<comment>', '<fixme>', '<margin>', '<highlight>']:
                    if tag == '<highlight>':
                        INLINE_HIGHLIGHT = True
                    INLINE_TAG_STACK.append(tag)
                else:
                    if tag == '</highlight>':
                        INLINE_HIGHLIGHT = False
                    INLINE_TAG_STACK.pop()
                if docFormat in ['html', 'html5']:
                    return html(HTML_TEXT[tag])
                elif docFormat == 'revealjs':
                    return html(REVEALJS_TEXT[tag])
                else:
                    return []

        elif tag.startswith('<i ') and tag.endswith('>'):  # Index
            if docFormat == 'latex':
                return latex('\\index{{{}}}'.format(tag[3:-1]))
            else:
                return []

        elif tag.startswith('<l ') and tag.endswith('>'):
            # My definition of a label
            if docFormat == 'latex':
                return latex('\\label{{{}}}'.format(tag[3:-1]))
            elif docFormat in ['html', 'html5']:
                return html('<a name="{}"></a>'.format(tag[3:-1]))

        elif tag.startswith('<r ') and tag.endswith('>'):
            # My definition of a reference
            if docFormat == 'latex':
                return latex('\\cref{{{}}}'.format(tag[3:-1]))
            elif docFormat in ['html', 'html5']:
                return html('<a href="#{}">here</a>'.format(tag[3:-1]))

        elif tag.startswith('<rp ') and tag.endswith('>'):
            # My definition of a page reference
            if docFormat == 'latex':
                return latex('\\cpageref{{{}}}'.format(tag[4:-1]))
            elif docFormat in ['html', 'html5']:
                return html('<a href="#{}">here</a>'.format(tag[4:-1]))

    elif not draft and (INLINE_COMMENT or INLINE_MARGIN):
        # Suppress all output
        return []

    # Check some cases at beginnings of paragraphs
    elif key == 'Para':
        try:
            # If translating to LaTeX, beginning a paragraph with '< '
            # will cause '\noindent{}' to be output first.
            if value[0]['t'] == 'Str' and value[0]['c'] == '<' \
                    and value[1]['t'] == 'Space':
                if docFormat == 'latex':
                    return Para([latex('\\noindent{}')] + value[2:])
                elif docFormat in ['html', 'html5']:
                    return Para([html('<div class="noindent">')] + value[2:] +
                                [html('</div>')])
                else:
                    return Para(value[2:])

            else:
                return  # Normal paragraph, not affected by this filter

        except:
            return  # May happen if the paragraph is empty.

    # Check for tikz CodeBlock. If it exists, try typesetting figure
    elif key == 'CodeBlock':
        (id, classes, attributes), code = value
        if 'tikz' in classes or '\\begin{tikzpicture}' in code:
            if 'fontfamily' in meta:
                font = meta['fontfamily']['c'][0]['c']
            else:
                font = DEFAULT_FONT
            outfile = path.join(IMAGE_PATH, my_sha1(code + font))
            filetype = '.pdf' if docFormat == 'latex' else '.png'
            sourceFile = outfile + filetype
            caption = ''
            library = ''
            for a, b in attributes:
                if a == 'caption':
                    caption = b
                elif a == 'tikzlibrary':
                    library = b
            if not path.isfile(sourceFile):
                try:
                    mkdir(IMAGE_PATH)
                    debug('Created directory {}\n\n'.format(IMAGE_PATH))
                except OSError:
                    pass
                codeHeader = '\\documentclass{{standalone}}\n\\usepackage{{{}}}\n\\usepackage{{tikz}}\n'.format(
                    font)
                if library:
                    codeHeader += '\\usetikzlibrary{{{}}}\n'.format(library)
                codeHeader += '\\begin{document}\n'
                codeFooter = '\n\\end{document}\n'
                tikz2image(codeHeader + code + codeFooter, filetype, outfile)
                debug('Created image {}\n\n'.format(sourceFile))
            if caption:
                # Need to run this through pandoc to get JSON
                # representation so that captions can be docFormatted text.
                jsonString = toFormat(caption, 'markdown', 'json')
                if "blocks" in jsonString:
                    formattedCaption = eval(jsonString)["blocks"][0]['c']
                else:  # old API
                    formattedCaption = eval(jsonString)[1][0]['c']
            else:
                formattedCaption = [Str('')]
            return Para([
                Image((id, classes, attributes), formattedCaption,
                      [sourceFile, caption])
            ])
        else:  # CodeBlock, but not tikZ
            return

    else:  # Not text this filter modifies....
        return
Exemple #18
0
def _add_markup(fmt, thm, value):
    """Adds markup to the output."""

    attrs = thm['attrs']
    ret = None

    if fmt in ['latex', 'beamer']:

        # remark: tagged theorems are not (yet) supported

        # Present theorem as a definition list
        env = attrs.id.split(':')[0]

        tmp = value[0][0]['c'][1]
        title = ''
        if len(tmp) >= 1:
            title = '[%s]' % stringify(tmp)

        start = RawBlock('tex',
                         r'\begin{%s}%s%s' % \
                         (env, title,
                          '' if thm['is_unreferenceable'] else
                          r'\label{%s} '%attrs.id))
        endtags = RawBlock('tex', r'\end{%s}' % env)
        content = value[1][0]
        ret = [start] + content + [endtags]

    elif fmt in ('html', 'html5', 'epub', 'epub2', 'epub3'):
        if isinstance(targets[attrs.id].num, int):  # Numbered reference
            num = Str(' %d' % targets[attrs.id].num)
        else:  # Tagged reference
            assert isinstance(targets[attrs.id].num, STRTYPES)
            text = ' ' + targets[attrs.id].num
            if text.startswith('$') and text.endswith('$'):
                math = text.replace(' ', r'\ ')[1:-1]
                num = Math({"t": "InlineMath", "c": []}, math)
            else:  # Text
                num = Str(text)

        # Present theorem as a definition list
        outer = RawBlock('html',
                         '<dl%sclass="theoremnos">' % \
                         (' ' if thm['is_unreferenceable'] else
                          ' id="%s" '%attrs.id))
        name = names[attrs.id.split(':')[0]]
        head = RawBlock('html', '<dt>')
        endhead = RawBlock('html', '</dt><dd>')
        title = value[0][0]['c'][1]
        if len(title) >= 1:
            title.insert(0, Str(' ('))
            title.insert(0, num)
            title.append(Str(')'))
        else:
            title.append(num)

        title.insert(0, Str('%s' % name))
        title.append(Str(':'))
        content = value[1][0]
        endtags = RawBlock('html', '</dd></dl>')
        ret = [outer, head, Plain(title), endhead] + content + [endtags]

    # To do: define default behaviour

    return ret
def pygments(key, value, format, _):

    global FIG_COUNTER
    global CHAPTER_NUM

    # Used for figure log
    if format == "muse":

        if key == "Header":
            level = value[0]
            if level == 1:
                try:
                    CHAPTER_NUM = int(value[1][0].split("-")[1])
                    FIG_COUNTER = 0
                except:
                    pass

        if key == "Div":
            [[ident, classes, keyvals], code] = value
            div_type = classes[0]

            if div_type == "figure":
                FIG_COUNTER += 1
                fig_id = code[2]["c"][0]["c"].split(")")[0][2:]
                html = code[0]["c"][0]["c"][1]
                _, src, _, alt, *_ = html.split("\"")
                src = src.split("/")[-1]
                redraw = "Redraw" if src.startswith(
                    "diagram_") else "Use as-is"
                stderr.write(
                    f"{CHAPTER_NUM},{FIG_COUNTER},Yes,\"N/A\",{src},{redraw},\"{alt}\"\n"
                )

        return None

    if format == "asciidoc":

        # Fix chapter cross ref
        # if key == "Link" and value[2][0].startswith("#chapter"):
        #     return RawInline("asciidoc", f"<<{value[2][0][1:]}>>")

        # if key == "Header":
        #     level = value[0]
        #     chapter_id = "_".join(value[1][0].split("-")[2:])
        #     if level == 1:
        #         stderr.write(f"HEADER: {value}\n\n")
        #         stderr.write(f"HEADER_ID: {chapter_id}\n\n")

        # Only keep <!--A...A---> comments
        if key == "RawBlock":
            try:
                if (match := comment_adoc_re.fullmatch(value[1])):
                    return RawBlock("asciidoc", match.group(1))
            except:
                pass

        # Fix references to figures
        if (key == "Str") and value.startswith("@ref"):
            # stderr.write(f"{key}\t{value}\n")
            #_, ref_type, ref_id, *rest = re.split("\(|:|\)", value)

            match = ref_re.fullmatch(value)
            ref_type = match.group(1)
            ref_id = match.group(2)
            ref_rest = match.group(3)
            new_ref = f"<<{ref_type}:{ref_id}>>{ref_rest}"
            # stderr.write(new_ref + "\n")
            return Str(new_ref)

        elif key == "Div":
            [[ident, classes, keyvals], code] = value
            div_type = classes[0]

            # Fix admonition
            if div_type.startswith("rmd"):
                adm_type = div_type[3:]
                return Plain([Str(f"[{ADM_TYPE[adm_type]}]\n====\n")] +
                             code[0]["c"] + [Str("\n====\n\n")])

            # Fix figures
            elif div_type == "figure":
                fig_id = code[2]["c"][0]["c"].split(")")[0][2:]
                html = code[0]["c"][0]["c"][1]
                # stderr.write(f"{html}\n")
                _, src, _, alt, *_ = html.split("\"")
                return Plain(
                    [Str(f"[[{fig_id}]]\n.{alt}\nimage::{src}[\"{alt}\"]")])

        elif key == "CodeBlock":
            [[ident, classes, keyvals], code] = value
            if classes:
                language = classes[0]
                # stderr.write(f"{key}\t{value}\t{format}\n")
                html_code = conv.convert(code, full=False)
                html_code = html_code.replace("+", "&#43;")

                result = "[source,subs=\"+macros\"]\n----\n"
                for line in html_code.split("\n"):
                    line += "<span></span>"
                    if match := callout_code_re.search(line):
                        line = callout_code_re.sub("", line)
                        line = f"+++{line}+++ <{match.group(1)}>"
                    else:
                        line = f"+++{line}+++"
                    result += line + "\n"
                result += "----\n\n"

                # html_code = "+++" + html_code.replace("\n", "<span></span>+++\n+++") + "<span></span>+++"
                html_code = html_code.replace("<span", "+++<span").replace(
                    "</span>", "</span>+++")
                #result = "[subs=callouts]\n++++\n<pre data-type=\"programlisting\" style=\"color: #4f4f4f\">" + html_code + "</pre>\n++++\n\n"
                # result = "[source,subs=\"+macros\"]\n----\n" + html_code + "\n----\n\n"

                # Turn code callout number into image
                # result = callout_code_re.sub(lambda x: f"<img src=\"callouts/{int(x.group(1))}.png\" alt=\"{int(x.group(1))}\">", result)
                # result = callout_code_re.sub(lambda x: f"<a class=\"co\"><img src=\"callouts/{int(x.group(1))}.png\" /></a>", result)
                # result = callout_code_re.sub(lambda x: f"<!--{int(x.group(1))}-->", result)
                # result = result.replace("+++<span></span>+++", "")
            else:
                result = code
            return RawBlock("asciidoc", result)