Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
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