def handle_request(self, latex_expr): """Uploads LaTeX formated equations to imgur and returns a URL. Args: latex_expr: string that is to converte to LaTeX, requires that string is enclosed by $. >>> handle_request("$\int \sqrt{1+\cos x + \sin x} dx$") Returns: A tuple (str, (int, int)), where str is the url, on imgur and the tuples are the dimensions of the image (width, height). """ # create a bare bones latex document with only the one line specified from the user in the document. doc = Document(documentclass='minimal') doc.packages = [Package(NoEscape(i)) for i in self.packages.split(',')] doc.append(NoEscape(latex_expr)) doc.generate_pdf('default', compiler_args=[ '-no-shell-escape', ], compiler="pdflatex", clean=True, clean_tex=True) # These are normal Linux commands that are used to convert the pdf # file created by pylatex into a snippet os.system("pdfcrop default.pdf") os.system("pdftoppm default-crop.pdf|pnmtopng > default.png") path = os.path.abspath('default.png') uploaded_image = self._client.upload_image(path, title="LaTeX") return uploaded_image.link, OnlineImage.get_local_image_info(path)
def _upload_problem(self, problem): """Uploads a specified problem to imgur. Returns: A tuple (str, (int, int)), where str is the url, on imgur and the tuples are the dimensions of the image (width, height). Raises: LatexParsingException : there was an issue parsing the document """ default_doc = [] # populate doc with the appropriate problem for line in problem[0]: # these first two statements are for wrapping the title around in a minipage which allows # the problem to be generated on one page and doesn't invoke \newpage if line == '\\begin{document}': default_doc.append(NoEscape(line)) default_doc.append(NoEscape('\\begin{minipage}{\\textwidth}')) elif line == '\\maketitle': default_doc.append(NoEscape(line)) default_doc.append(NoEscape('\\end{minipage}')) elif line == '\\end{itemize}': for line2 in problem[1]: default_doc.append(NoEscape(line2)) default_doc.append(NoEscape(line)) else: default_doc.append(NoEscape(line)) doc_class_line = NoEscape(default_doc[0]) use_pkg_line = NoEscape(default_doc[1]) # skip twocolumn since it makes the problem look spread awfully opts = filter(lambda pkg: pkg != 'twocolumn', doc_class_line[doc_class_line.find('[') + 1: doc_class_line.find(']')].split(',')) args = NoEscape(doc_class_line[doc_class_line.find('{') + 1: doc_class_line.find('}')]) doc = Document(documentclass=Command('documentclass', options=opts, arguments=args)) # load packages doc.packages = [Package(i) for i in use_pkg_line[use_pkg_line.find('{') + 1: use_pkg_line.find('}')].split(',')] # position right after \begin{document} it = 4 while default_doc[it].strip() != '\end{document}': doc.append(NoEscape(default_doc[it])) it += 1 # fail safe for future problems which may not parse correctly try: doc.generate_pdf('default', compiler="pdflatex") except: raise LatexParsingException # These are normal Linux commands that are used to convert the pdf # file created by pylatex into a snippet os.system("pdfcrop default.pdf") os.system("pdftoppm default-crop.pdf|pnmtopng > default.png") path = os.path.abspath('default.png') uploaded_image = self._client.upload_image(path, title="LaTeX") return uploaded_image.link, OnlineImage.get_local_image_info(path)
def handle_request(self, latex_expr): """Uploads LaTeX formated equations to imgur and returns a URL. Args: latex_expr: string that is to converte to LaTeX, requires that string is enclosed by $. >>> handle_request("$\int \sqrt{1+\cos x + \sin x} dx$") Returns: A tuple (str, (int, int)), where str is the url, on imgur and the tuples are the dimensions of the image (width, height). """ # create a bare bones latex document with only the one line specified from the user in the document. doc = Document(documentclass='minimal') doc.packages = [Package(NoEscape(i)) for i in self.packages.split(',')] doc.append(NoEscape(latex_expr)) doc.generate_pdf('default', compiler_args=['-no-shell-escape', ], compiler="pdflatex", clean=True, clean_tex=True) # These are normal Linux commands that are used to convert the pdf # file created by pylatex into a snippet os.system("pdfcrop default.pdf") os.system("pdftoppm default-crop.pdf|pnmtopng > default.png") path = os.path.abspath('default.png') uploaded_image = self._client.upload_image(path, title="LaTeX") return uploaded_image.link, OnlineImage.get_local_image_info(path)
def _upload_problem(self, problem): """Uploads a specified problem to imgur. Returns: A tuple (str, (int, int)), where str is the url, on imgur and the tuples are the dimensions of the image (width, height). Raises: LatexParsingException : there was an issue parsing the document """ default_doc = [] # populate doc with the appropriate problem for line in problem[0]: # these first two statements are for wrapping the title around in a minipage which allows # the problem to be generated on one page and doesn't invoke \newpage if line == '\\begin{document}': default_doc.append(NoEscape(line)) default_doc.append(NoEscape('\\begin{minipage}{\\textwidth}')) elif line == '\\maketitle': default_doc.append(NoEscape(line)) default_doc.append(NoEscape('\\end{minipage}')) elif line == '\\end{itemize}': for line2 in problem[1]: default_doc.append(NoEscape(line2)) default_doc.append(NoEscape(line)) else: default_doc.append(NoEscape(line)) doc_class_line = NoEscape(default_doc[0]) use_pkg_line = NoEscape(default_doc[1]) # skip twocolumn since it makes the problem look spread awfully opts = filter( lambda pkg: pkg != 'twocolumn', doc_class_line[doc_class_line.find('[') + 1:doc_class_line.find(']')].split(',')) args = NoEscape(doc_class_line[doc_class_line.find('{') + 1:doc_class_line.find('}')]) doc = Document(documentclass=Command( 'documentclass', options=opts, arguments=args)) # load packages doc.packages = [ Package(i) for i in use_pkg_line[use_pkg_line.find('{') + 1:use_pkg_line.find('}')].split(',') ] # position right after \begin{document} it = 4 while default_doc[it].strip() != '\end{document}': doc.append(NoEscape(default_doc[it])) it += 1 # fail safe for future problems which may not parse correctly try: doc.generate_pdf('default', compiler="pdflatex") except: raise LatexParsingException # These are normal Linux commands that are used to convert the pdf # file created by pylatex into a snippet os.system("pdfcrop default.pdf") os.system("pdftoppm default-crop.pdf|pnmtopng > default.png") path = os.path.abspath('default.png') uploaded_image = self._client.upload_image(path, title="LaTeX") return uploaded_image.link, OnlineImage.get_local_image_info(path)
def get_document_sizes(document_class): """Get useful document sizes given a LaTeX document class. Args: document_class: dict with ``documentclass`` and ``document_options``. It may optionally contain a list of LaTeX packages under ``packages`` as well as any other argument acceptable by ``pylatex.document``. Examples: You may use one of the available document_classes. >>> from pprint import pprint >>> from pubplot.document_classes import ieee_infocom >>> sizes_dict = get_document_sizes(ieee_infocom) >>> pprint(sizes_dict) {'Huge': 24.0, 'LARGE': 17.0, 'Large': 14.0, 'caption': 8.0, 'columnwidth': 252.0, 'footnotesize': 8.0, 'huge': 20.0, 'large': 12.0, 'normalsize': 10.0, 'scriptsize': 7.0, 'small': 9.0, 'textwidth': 516.0, 'tiny': 5.0} Or provide your own, using a dict >>> document_class = { ... 'documentclass': 'IEEEtran', ... 'document_options': ['10pt', 'conference', 'letterpaper'] ... } >>> sizes_dict = get_document_sizes(document_class) >>> pprint(sizes_dict) {'Huge': 24.0, 'LARGE': 17.0, 'Large': 14.0, 'caption': 8.0, 'columnwidth': 252.0, 'footnotesize': 8.0, 'huge': 20.0, 'large': 12.0, 'normalsize': 10.0, 'scriptsize': 7.0, 'small': 9.0, 'textwidth': 516.0, 'tiny': 5.0} Returns: A dictionary containing sizes - columnwidth - textwidth - tiny - scriptsize - footnotesize - small - normalsize - large - Large - LARGE - huge - Huge - caption """ def log_with_name(name, value): return '\\wlog{{{}{}={}}}'.format(LOG_PATTERN, name, value) def log_text_size(text_size_name): return '\\{} a {} \n\n'.format( text_size_name, log_with_name(text_size_name, r'\f@size pt')) get_sizes_command = r""" \makeatletter \newcommand\getsizes{% """ + log_with_name('columnwidth', r'\the\columnwidth') + r""" """ + log_with_name('textwidth', r'\the\textwidth') + r""" \begin{figure} \centering \fbox{ \begin{minipage}[c][0.1\textheight][c]{\columnwidth} \centering{Dummy Image} \end{minipage} } \caption{a """ + log_with_name('caption', r'\f@size pt') + r""" } \end{figure} """ for size in LATEX_BUILT_IN_SIZES: get_sizes_command += log_text_size(size) get_sizes_command += '}' temp_doc_name = next(tempfile._get_candidate_names()) document_kwargs = document_class.copy() packages = document_kwargs.pop('packages', []) doc = Document(temp_doc_name, **document_kwargs) doc.packages = packages doc.preamble.append(NoEscape(get_sizes_command)) doc.append(Command('title', 'Title')) doc.append(Command('maketitle')) doc.append('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam c' 'onsectetur volutpat tellus vel ultricies. Donec ullamcorper or' 'ci quis ante volutpat efficitur. Aenean at rhoncus nibh. Morbi' ' vitae justo velit. Curabitur eget condimentum quam, nec accum' 'san nulla. Nam tempor sem id tellus consectetur condimentum. N' 'ullam id lacus purus. Nam nisi nisi, tempus ac ligula luctus, ' 'mollis volutpat odio. Mauris euismod mi nec rutrum tempor.\n' * 20) doc.append(NoEscape(r'\getsizes')) try: doc.generate_pdf(temp_doc_name, clean=False) except subprocess.CalledProcessError: pass with open(temp_doc_name + '.log', 'r') as f: lines = f.read().splitlines() sizes_dict = {} for l in lines: if l.startswith(LOG_PATTERN): variable, value = l.split('=') variable = variable[len(LOG_PATTERN):] sizes_dict[variable] = float(value[0:-2]) list(map(os.remove, glob.glob(temp_doc_name + '.*'))) return sizes_dict