示例#1
0
    def figure_replacement(self, key, value, format, metadata):
        """Replace figures with appropriate representation.

        This works with Figure, which is our special type for images
        with attributes. This allows us to set an id in the attributes.

        The other way of doing it would be to pull out a '\label{(.*)}'
        from the caption of an Image and use that to update the references.
        """
        caption, (filename, alt), attr = value

        if 'unnumbered' in attr[1]:
            fcaption = caption
        else:
            self.fig_replacement_count += 1
            if not attr[0]:
                attr[0] = self.auto_fig_id(self.fig_replacement_count)

            ref = self.references[attr[0]]
            if caption:
                fcaption = [
                    pf.Str('Figure'),
                    pf.Space(),
                    pf.Str(str(ref['id']) + ':'),
                    pf.Space()
                ] + caption
            else:
                fcaption = [
                    pf.Str('Figure'),
                    pf.Space(),
                    pf.Str(str(ref['id']))
                ]


#        if 'figure' not in attr[1]:
#            # FIXME: Currently adding this in html_figure() and html5_figure()
#            attr[1].append('figure')

        if format == 'latex' or format == 'beamer':
            return latex_figure(attr, filename, caption, alt)
        elif format == 'html':
            return html_figure(attr, filename, fcaption, alt)
        elif format == 'html5':
            return html5_figure(attr, filename, fcaption, alt)
        elif format == 'markdown':
            return markdown_figure(attr, filename, fcaption, alt)
        else:
            image = pf.Image(attr, fcaption, (filename, alt))
            return pf.Para([image])
示例#2
0
def process_buffer(buffer, new_value, item=None):
    if buffer:
        text = ''.join(buffer)

        try:
            translated_text = translate.translate(text)
        except TypeError:
            translated_text = text
        except json.decoder.JSONDecodeError as e:
            print('Failed to translate', str(e), file=sys.stderr)
            sys.exit(1)

        debug(f'Translate: "{text}" -> "{translated_text}"')

        if text and text[0].isupper() and not translated_text[0].isupper():
            translated_text = translated_text[0].upper() + translated_text[1:]

        if text.startswith(' ') and not translated_text.startswith(' '):
            translated_text = ' ' + translated_text

        if text.endswith(' ') and not translated_text.endswith(' '):
            translated_text = translated_text + ' '

        for token in translated_text.split(' '):
            new_value.append(pandocfilters.Str(token))
            new_value.append(pandocfilters.Space())

        if item is None and len(new_value):
            new_value.pop(len(new_value) - 1)
        else:
            new_value[-1] = item
    elif item:
        new_value.append(item)
示例#3
0
    def convert_internal_refs(self, key, value, format, metadata):
        """Convert all internal links from '#blah' into format
        specified in self.replacements.
        """
        if key != 'Cite':
            return None

        citations, inlines = value

        if len(citations) > 1:
            '''
            Note: Need to check that *all* of the citations in a
            multicitation are in the reference list. If not, the citation
            is bibliographic, and we want LaTeX to handle it, so just
            return unmodified.
            '''
            for citation in citations:
                if citation['citationId'] not in self.references:
                    return
            return self.convert_multiref(key, value, format, metadata)

        else:
            citation = citations[0]

        prefix = citation['citationPrefix']
        suffix = citation['citationSuffix']

        label = citation['citationId']

        if label not in self.references:
            return

        if prefix:
            prefix += [pf.Space()]

        rtype = self.references[label]['type']
        n = self.references[label]['id']
        text = self.replacements[rtype].format(n)

        if format in ['latex', 'beamer'] and self.autoref:
            link = pf.RawInline('latex',
                                '\\cref{{{label}}}'.format(label=label))
            return prefix + [link] + suffix

        elif format in ['latex', 'beamer'] and not self.autoref:
            link = pf.RawInline('latex',
                                '\\ref{{{label}}}'.format(label=label))
            return prefix + [link] + suffix

        else:
            link = pf.Link(["", [], []], [pf.Str(text)], ('#' + label, ''))
            return prefix + [link] + suffix
示例#4
0
def process_buffer(buffer, new_value, item=None, is_header=False):
    if buffer:
        text = ''.join(buffer)

        try:
            translated_text = translate.translate(text)
        except TypeError:
            translated_text = text
        except json.decoder.JSONDecodeError as e:
            print('Failed to translate', str(e), file=sys.stderr)
            sys.exit(1)

        debug(f'Translate: "{text}" -> "{translated_text}"')

        if text and text[0].isupper() and not translated_text[0].isupper():
            translated_text = translated_text[0].upper() + translated_text[1:]

        if text.startswith(' ') and not translated_text.startswith(' '):
            translated_text = ' ' + translated_text

        if text.endswith(' ') and not translated_text.endswith(' '):
            translated_text = translated_text + ' '

        if is_header and translated_text.endswith('.'):
            translated_text = translated_text.rstrip('.')

        title_case = is_header and translate.default_target_language == 'en' and text[
            0].isupper()
        title_case_whitelist = {
            'a', 'an', 'the', 'and', 'or', 'that', 'of', 'on', 'for', 'from',
            'with', 'to', 'in'
        }
        is_first_iteration = True
        for token in translated_text.split(' '):
            if title_case and token.isascii() and not token.isupper():
                if len(token) > 1 and token.lower(
                ) not in title_case_whitelist:
                    token = token[0].upper() + token[1:]
                elif not is_first_iteration:
                    token = token.lower()
            is_first_iteration = False

            new_value.append(pandocfilters.Str(token))
            new_value.append(pandocfilters.Space())

        if item is None and len(new_value):
            new_value.pop(len(new_value) - 1)
        else:
            new_value[-1] = item
    elif item:
        new_value.append(item)
示例#5
0
    def tableattrs_replacement(self, key, value, format, metadata):
        """Replace TableAttrs with appropriate representation.

        TableAttrs is our special type for tables with attributes,
        allowing us to set an id in the attributes.
        """
        caption, alignment, size, headers, rows, (id, classes, kvs) = value

        if 'unnumbered' in classes:
            fcaption = caption
        else:
            self.table_replacement_count += 1
            if not id:
                id = self.auto_table_id(self.table_replacement_count)

            ref = self.references[id]
            if caption:
                fcaption = [
                    pf.Str('Table'),
                    pf.Space(),
                    pf.Str(str(ref['id']) + ':'),
                    pf.Space()
                ] + caption
            else:
                fcaption = [
                    pf.Str('Table'),
                    pf.Space(),
                    pf.Str(str(ref['id']))
                ]

        if format == 'latex' or format == 'beamer':
            return latex_table(caption, alignment, size, headers, rows, id,
                               classes, kvs)
        else:
            return pf.Div([id, classes, kvs],
                          [pf.Table(fcaption, alignment, size, headers, rows)])
示例#6
0
def process_buffer(buffer, new_value, item=None, is_header=False):
    if buffer:
        text = ''.join(buffer)

        try:
            translated_text = translate.translate(text)
        except TypeError:
            translated_text = text
        except json.decoder.JSONDecodeError as e:
            print('Failed to translate', str(e), file=sys.stderr)
            sys.exit(1)

        debug(f'Translate: "{text}" -> "{translated_text}"')

        if text and text[0].isupper() and not translated_text[0].isupper():
            translated_text = translated_text.capitalize()

        if text.startswith(' ') and not translated_text.startswith(' '):
            translated_text = ' ' + translated_text

        if text.endswith(' ') and not translated_text.endswith(' '):
            translated_text = translated_text + ' '

        title_case = is_header and translate.default_target_language == 'en' and text[
            0].isupper()
        title_case_whitelist = {'a', 'an', 'the', 'and', 'or'}
        for token in translated_text.split(' '):
            if title_case and not token.isupper():
                if token not in title_case_whitelist:
                    token = token.capitalize()

            new_value.append(pandocfilters.Str(token))
            new_value.append(pandocfilters.Space())

        if item is None and len(new_value):
            new_value.pop(len(new_value) - 1)
        else:
            new_value[-1] = item
    elif item:
        new_value.append(item)
示例#7
0
def translate_filter(key, value, _format, _):
    if key not in ['Space', 'Str']:
        debug(key, value)
    try:
        cls = getattr(pandocfilters, key)
    except AttributeError:
        return

    if key == 'Para' and value:
        marker = value[0].get('c')
        if isinstance(marker,
                      str) and marker.startswith('!!!') and len(value) > 2:
            # Admonition case
            if marker != '!!!':
                # Lost space after !!! case
                value.insert(1, pandocfilters.Str(marker[3:]))
                value.insert(1, pandocfilters.Space())
                value[0]['c'] = '!!!'
            admonition_value = []
            remaining_para_value = []
            in_admonition = True
            for item in value:
                if in_admonition:
                    if item.get('t') == 'SoftBreak':
                        in_admonition = False
                    else:
                        admonition_value.append(item)
                else:
                    remaining_para_value.append(item)

            break_value = [
                pandocfilters.LineBreak(),
                pandocfilters.Str(' ' * 4)
            ]
            if admonition_value[-1].get('t') == 'Quoted':
                text = process_sentence(admonition_value[-1]['c'][-1])
                text[0]['c'] = '"' + text[0]['c']
                text[-1]['c'] = text[-1]['c'] + '"'
                admonition_value.pop(-1)
                admonition_value += text
            else:
                text = admonition_value[-1].get('c')
                if text:
                    text = translate(text[0].upper() + text[1:])
                    admonition_value.append(pandocfilters.Space())
                    admonition_value.append(pandocfilters.Str(f'"{text}"'))

            return cls(admonition_value + break_value +
                       process_sentence(remaining_para_value))
        else:
            return cls(process_sentence(value))
    elif key == 'Plain' or key == 'Strong' or key == 'Emph':
        return cls(process_sentence(value))
    elif key == 'Link':
        try:
            # Plain links case
            if value[2][0] == value[1][0].get('c'):
                return pandocfilters.Str(value[2][0])
        except IndexError:
            pass
        value[1] = process_sentence(value[1])
        return cls(*value)
    elif key == 'Header':
        # TODO: title case header in en
        if '_' not in value[1][0]:  # Preserve some manually specified anchors
            value[1][0] = slugify.slugify(value[1][0],
                                          separator='-',
                                          word_boundary=True,
                                          save_order=True)
        value[2] = process_sentence(value[2])
        return cls(*value)
    elif key == 'SoftBreak':
        return pandocfilters.LineBreak()

    return
示例#8
0
def translate_filter(key, value, _format, _):
    if key not in ['Space', 'Str']:
        debug(key, value)
    try:
        cls = getattr(pandocfilters, key)
    except AttributeError:
        return

    if key == 'Para' and value:
        marker = value[0].get('c')
        if isinstance(marker, str) and marker.startswith('!!!') and len(value) > 2:
            # Admonition case
            if marker != '!!!':
                # Lost space after !!! case
                value.insert(1, pandocfilters.Str(marker[3:]))
                value.insert(1, pandocfilters.Space())
                value[0]['c'] = '!!!'
            admonition_value = []
            remaining_para_value = []
            in_admonition = True
            break_value = [pandocfilters.LineBreak(), pandocfilters.Str(' ' * 4)]
            for item in value:
                if in_admonition:
                    if item.get('t') == 'SoftBreak':
                        in_admonition = False
                    else:
                        admonition_value.append(item)
                else:
                    if item.get('t') == 'SoftBreak':
                        remaining_para_value += break_value
                    else:
                        remaining_para_value.append(item)

            if admonition_value[-1].get('t') == 'Quoted':
                text = process_sentence(admonition_value[-1]['c'][-1])
                text[0]['c'] = '"' + text[0]['c']
                text[-1]['c'] = text[-1]['c'] + '"'
                admonition_value.pop(-1)
                admonition_value += text
            else:
                text = admonition_value[-1].get('c')
                if text:
                    text = translate.translate(text[0].upper() + text[1:])
                    admonition_value.append(pandocfilters.Space())
                    admonition_value.append(pandocfilters.Str(f'"{text}"'))

            return cls(admonition_value + break_value + process_sentence(remaining_para_value))
        else:
            return cls(process_sentence(value))
    elif key == 'Plain' or key == 'Strong' or key == 'Emph':
        return cls(process_sentence(value))
    elif key == 'Link':
        try:
            # Plain links case
            if value[2][0] == value[1][0].get('c'):
                return pandocfilters.Str(value[2][0])
        except IndexError:
            pass

        value[1] = process_sentence(value[1])
        href = value[2][0]
        if not (href.startswith('http') or href.startswith('#')):
            anchor = None
            attempts = 10
            if '#' in href:
                href, anchor = href.split('#', 1)
            if href.endswith('.md') and not href.startswith('/'):
                parts = [part for part in os.environ['INPUT'].split('/') if len(part) == 2]
                lang = parts[-1]
                script_path = os.path.dirname(__file__)
                base_path = os.path.abspath(f'{script_path}/../../{lang}')
                href = os.path.join(
                    os.path.relpath(base_path, os.path.dirname(os.environ['INPUT'])),
                    os.path.relpath(href, base_path)
                )
            if anchor:
                href = f'{href}#{anchor}'
            value[2][0] = href
        return cls(*value)
    elif key == 'Header':
        if value[1][0].islower() and '_' not in value[1][0]:  # Preserve some manually specified anchors
            value[1][0] = slugify.slugify(value[1][0], separator='-', word_boundary=True, save_order=True)

        # TODO: title case header in en
        value[2] = process_sentence(value[2], is_header=True)
        return cls(*value)
    elif key == 'SoftBreak':
        return pandocfilters.LineBreak()

    return
示例#9
0
def strip_code(key, value, format, meta):
    if key in ('CodeBlock', 'Header'):
        return pf.Null()
    elif key in ('DisplayMath'):
        return pf.Space()