def render(self, source): proc = Subprocess(['docker', 'run', '-i', 'dmoj/texbox:latest'], stdin=Subprocess.STREAM, stdout=Subprocess.STREAM, stderr=Subprocess.STREAM) input_task = self._write_and_close(proc.stdin, utf8bytes(source)) _, output, log = yield [ input_task, proc.stdout.read_until_close(), proc.stderr.read_until_close() ] try: yield proc.wait_for_exit() except subprocess.CalledProcessError: raise RuntimeError('Failed to run docker, full log:\n' + utf8text(log, errors='backslashreplace')) try: width, height, svg_len = header.unpack(output[:header.size]) svg = output[header.size:header.size + svg_len] rest = output[header.size + svg_len:] png_len, = size_struct.unpack(rest[:size_struct.size]) png = rest[size_struct.size:size_struct.size + png_len] except struct.error: raise RuntimeError('corrupted output from texbox') if len(svg) != svg_len or b'<svg' not in svg: raise RuntimeError('corrupted SVG file from texbox') if len(png) != png_len or b'\x89PNG' not in png: raise RuntimeError('corrupted PNG file from texbox') return { 'svg': utf8text(svg), 'png': png, 'meta': { 'width': width, 'height': height } }
def dvi_to_svg(self): dvisvgm = Subprocess([ self.backend.dvisvgm_path, '--verbosity=1', '--no-fonts', 'render.dvi' ], stdout=Subprocess.STREAM, stderr=subprocess.STDOUT, cwd=self.dir) log = yield dvisvgm.stdout.read_until_close() try: yield dvisvgm.wait_for_exit() except subprocess.CalledProcessError: raise RuntimeError('Failed to run dvisvgm, full log:\n' + utf8text(log, errors='backslashreplace'))
def latex_to_dvi(self): latex = Subprocess([ self.backend.latex_path, '-halt-on-error', '-interaction=nonstopmode', 'render.tex' ], stdout=Subprocess.STREAM, stderr=subprocess.STDOUT, cwd=self.dir) log = yield latex.stdout.read_until_close() try: yield latex.wait_for_exit() except subprocess.CalledProcessError: raise RuntimeError('Failed to run latex, full log:\n' + utf8text(log, errors='backslashreplace'))
def render(self, source): with open(os.path.join(self.dir, 'render.tex'), 'wb') as f: f.write(utf8bytes(source)) yield self.latex_to_dvi() yield self.dvi_to_svg() png, width, height = yield self.svg_to_png() with open(os.path.join(self.dir, 'render.svg'), 'rb') as f: svg = utf8text(f.read()) return { 'png': png, 'svg': svg, 'meta': { 'width': width, 'height': height } }
def svg_to_png(self): convert = Subprocess( [self.backend.convert_path, '-identify', 'render.svg', 'png:-'], cwd=self.dir, stderr=Subprocess.STREAM, stdin=self.devnull, stdout=Subprocess.STREAM) out, err = yield [ convert.stdout.read_until_close(), convert.stderr.read_until_close() ] try: yield convert.wait_for_exit() except subprocess.CalledProcessError: raise RuntimeError('Failed to run convert, full log:\n' + utf8text(log, errors='backslashreplace')) ident, _, out = out.partition(b'\n') width, height = redimensions.match(ident).groups() return out, int(width), int(height)