Exemplo n.º 1
0
def afterframe(s):
    global lastsection, lastsubsection
    return [
        pf.Header(1, ('', ['unnumbered'], []), [pf.Str(lastsection)]),
        pf.Header(2, ('', ['unnumbered'], []), [pf.Str(lastsubsection)]),
        lb(s)
    ]
Exemplo n.º 2
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])
Exemplo n.º 3
0
Arquivo: bridge.py Projeto: dd0/bridge
def suit_symbols(key, value, fmt, meta):
    if key == 'Str':
        abbrevs = ['!C', '!D', '!H', '!S', '!N']
        orig_value = value

        if fmt != 'latex':
            suit_html = ['<font color=green>&clubs;</font>',
                         '<font color=orange>&diams;</font>',
                         '<font color=red>&hearts;</font>',
                         '<font color=blue>&spades;</font>',
                         'N']
            suit_other = ['C', 'D', 'H', 'S', 'N']

            suit_symbols = suit_html if fmt == 'html' else suit_other

            for (abbrev, symbol) in zip(abbrevs, suit_symbols):
                value = value.replace(abbrev, symbol)

        else:
            # LaTeX needs special handling (for mbox)
            value = value.replace('!N', 'N')
            suit = ['\\clubs{\\1}{\\2}',
                    '\\diamonds{\\1}{\\2}',
                    '\\hearts{\\1}{\\2}',
                    '\\spades{\\1}{\\2}']

            for (abbrev, symbol) in zip(abbrevs, suit):
                value = re.sub('([a-zA-Z0-9]*)%s([a-zA-Z0-9]*)' % abbrev,
                               symbol, value)

        if (fmt == 'html' or fmt == 'latex') and value != orig_value:
            return pf.RawInline(fmt, value)
        return pf.Str(value)
    else:
        return None
Exemplo n.º 4
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)
Exemplo n.º 5
0
    def result(self):
        'return FCB, Para(url()) and/or CodeBlock(stdout) as ordered'
        rv = []
        enc = sys.getdefaultencoding()  # result always unicode
        for output_elm in self.im_out:
            if output_elm == 'img':
                if os.path.isfile(self.outfile):
                    rv.append(pf.Para([self.url()]))
                else:
                    msg = '?? missing %s' % self.outfile
                    self.msg(1, '>>:', msg)
                    rv.append(pf.Para([pf.Str(msg)]))

            elif output_elm == 'fcb':
                rv.append(self.anon_codeblock())

            elif output_elm == 'stdout':
                if self.stdout:
                    attr = ['', self.classes, self.keyvals]
                    rv.append(pf.CodeBlock(attr, to_str(self.stdout, enc)))
                else:
                    self.msg(1, '>>:', 'stdout requested, but saw nothing')

            elif output_elm == 'stderr':
                if self.stderr:
                    attr = ['', self.classes, self.keyvals]
                    rv.append(pf.CodeBlock(attr, to_str(self.stderr, enc)))
                else:
                    self.msg(1, '>>:', 'stderr requested, but saw nothing')

        if not rv:
            return None  # no results; None keeps original FCB
        if len(rv) > 1:
            return rv  # multiple results
        return rv[0]  # just 1 block level element
def create_pandoc_multilink(strings, refs):
    inlines = [[pf.Str(str(s))] for s in strings]
    targets = [(r, "") for r in refs]
    links = [pf.Link(inline, target)
             for inline, target in zip(inlines, targets)]

    return join_items(links)
Exemplo n.º 7
0
 def render(self, watcher, inline):
     result = []
     betweenframes = False
     for i, f in enumerate(self._filenames):
         anim = self._anims[i]
         [options, slide] = self._mangleoptions(self._options[i])
         if slide:
             result.append(
                 li('\\slidefig{%s}{%s}' %
                    ('<' + anim + '>' if len(anim) > 0 else '', f)))
             betweenframes = True
             continue
         if i == 0 and len(self._caption) > 0:
             result.append(li('\\begin{%s}\n' % self._figtype))
         if i == 0 and len(self._caption) == 0 and not inline:
             result.append(li('{\\centering'))
         result.append(fig(f, options, anim))
         if i + 1 == len(self._filenames) and len(self._caption) > 0:
             result.extend([li('\\caption{'), li(self._caption), li('}\n')])
             result.append(li('\\end{%s}' % self._figtype))
         if i + 1 == len(self._filenames) and len(
                 self._caption) == 0 and not inline:
             result.append(li('\par}'))
     if inline:
         if betweenframes:
             return pf.Str('Unable to return paragraph when in inline mode')
         return result
     result = pf.Para(result)
     return watcher.betweenframes(result) if betweenframes else result
Exemplo n.º 8
0
Arquivo: bridge.py Projeto: dd0/bridge
def hand_diagram(hand):
    void = '--'
    hold = [x if len(x) > 0 else void for x in hand.split(',')]
    suit = ['!S', '!H', '!D', '!C']

    suits = [pf.Str(s + h) for s, h in zip(suit, hold)]
    res = sum(([x, pf.LineBreak()] for x in suits), [])[:-1]

    return pf.Plain(res)
    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 = pf.stringify(citation['citationPrefix'])
        suffix = pf.stringify(citation['citationSuffix'])

        if prefix:
            prefix += ' '

        label = citation['citationId']

        if label not in self.references:
            return

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

        if format == 'latex' and self.autoref:
            link = u'{pre}\\autoref{{{label}}}{post}'.format(pre=prefix,
                                                             label=label,
                                                             post=suffix)
            return pf.RawInline('latex', link)

        elif format == 'latex' and not self.autoref:
            link = u'{pre}\\ref{{{label}}}{post}'.format(pre=prefix,
                                                         label=label,
                                                         post=suffix)
            return pf.RawInline('latex', link)

        else:
            link_text = '{}{}{}'.format(prefix, text, suffix)
            link = pf.Link([pf.Str(link_text)], ('#' + label, ''))
            return link
Exemplo n.º 10
0
def include_filter(k, v, f, m):
    if k == 'Div':
        [[ident, classes, attrs], content] = v
        if 'include' in classes:
            with open(ident, 'r') as f:
                content = f.read()
                if 'code' in classes:
                    return pf.CodeBlock(
                        (ident, [get_attr_in_list(attrs, 'language')], []),
                        content)
                else:
                    return [pf.Para([pf.Str(content)])]
Exemplo n.º 11
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
Exemplo n.º 12
0
def add_eq_number_and_id(fmt, value, num, labelName):
    num = str(num)
    outer = pf.RawInline(
        'html',
        f'<span id="{labelName}" style="display: inline-block; position: relative; width: 100%;">'
    )
    inner = pf.RawInline(
        'html',
        '<span style="position: absolute; right: 0em; top: 50%; line-height: 0; ">'
    )
    eqno = pf.Str('(%s)' % num)
    endtags = pf.RawInline('html', '</span></span>')
    return [outer, elt('Math', 2)(*value), inner, eqno, endtags]
Exemplo n.º 13
0
Arquivo: bridge.py Projeto: dd0/bridge
def inline_hands(key, value, fmt, meta):
    if key == 'Code':
        hand = value[1]
        if hand.count(',') == 3 and len(hand) == 16:
            hold = hand.split(',')
            suit = ['!S', '!H', '!D', '!C']

            res = ' '.join(s + (h if len(h) > 0 else '--')
                           for s, h in zip(suit, hold))

            return pf.Str(res)

    return None
Exemplo n.º 14
0
    def convert_multiref(self, key, value, format, metadata):
        """Convert all internal links from '#blah' into format
        specified in self.replacements.
        """
        citations, inlines = value

        labels = [citation['citationId'] for citation in citations]

        if format in ['latex', 'beamer'] and self.autoref:
            link = self.latex_multi_autolink.format(pre='',
                                                    post='',
                                                    labels=','.join(labels))
            return RawInline('latex', link)

        elif format in ['latex', 'beamer'] and not self.autoref:
            link = ''.join(create_latex_multilink(labels))
            return RawInline('latex', link)

        else:
            D = [self.references[label] for label in labels]
            # uniquely ordered types
            types = list(OrderedDict.fromkeys(d['type'] for d in D))

            links = []

            for t in set(types):
                n = [d['id'] for d in D if d['type'] == t]
                labels = ['#' + d['label'] for d in D if d['type'] == t]
                multi_link = create_pandoc_multilink(n, labels)

                if len(labels) == 1:
                    multi_link.insert(0,
                                      pf.Str(self.replacements[t].format('')))
                else:
                    multi_link.insert(0, pf.Str(self.multi_replacements[t]))

                links.append(multi_link)

            return join_items(links, method='extend')
Exemplo n.º 15
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)
    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, target), attrs = value
        caption = pf.stringify(_caption)

        attr = PandocAttributes(attrs)

        if 'unnumbered' in attr.classes:
            star = '*'
            fcaption = caption
        else:
            self.fig_replacement_count += 1
            if not attr.id:
                attr.id = self.auto_fig_id(self.fig_replacement_count)

            ref = self.references[attr.id]
            star = ''
            if caption:
                fcaption = u'Figure {n}: {caption}'.format(n=ref['id'],
                                                           caption=caption)
            else:
                fcaption = u'Figure {n}'.format(n=ref['id'])

        if 'figure' not in attr.classes:
            attr.classes.insert(0, 'figure')

        if format in self.formats:
            figure = self.figure_styles[format].format(attr=attr,
                                                       filename=filename,
                                                       alt=fcaption,
                                                       fcaption=fcaption,
                                                       caption=caption,
                                                       star=star).encode('utf-8')

            return RawBlock(format, figure)

        else:
            alt = [pf.Str(fcaption)]
            target = (filename, '')
            image = pf.Image(alt, target)
            figure = pf.Para([image])
            return pf.Div(attr.to_pandoc(), [figure])
Exemplo n.º 17
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)])
Exemplo n.º 18
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)
Exemplo n.º 19
0
    def section_replacement(self, key, value, format, metadata):
        """Replace sections with appropriate representation.
        """
        level, attr, text = value
        label, classes, kvs = attr

        if 'unnumbered' in classes or not self.numbersections:
            pretext = ''
        else:
            ref = self.references[label]
            pretext = '{}. '.format(ref['id'])

        pretext = [pf.Str(pretext)]

        if format in ('html', 'html5', 'markdown'):
            return pf.Header(level, attr, pretext + text)

        elif format == 'latex' or format == 'beamer':
            # have to do this to get rid of hyperref
            return pf.Header(level, attr, text)

        else:
            return pf.Header(level, attr, pretext + text)
Exemplo n.º 20
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
Exemplo n.º 21
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
Exemplo n.º 22
0
Arquivo: bridge.py Projeto: dd0/bridge
 def make_cell(r):
     return [pf.Plain([pf.Str(r)])]