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])
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)
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
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 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)])
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)
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
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
def strip_code(key, value, format, meta): if key in ('CodeBlock', 'Header'): return pf.Null() elif key in ('DisplayMath'): return pf.Space()