Skip to content

Commit

Permalink
Trac #32650: sage.misc.latex: Replace have_... functions by Features
Browse files Browse the repository at this point in the history
... or more generally, replacing all uses of
`sage.misc.os_tools.have_program` by `Executable`

URL: https://trac.sagemath.org/32650
Reported by: mkoeppe
Ticket author(s): Sébastien Labbé
Reviewer(s): Matthias Koeppe
  • Loading branch information
Release Manager committed Nov 10, 2021
2 parents 741cb45 + 2ea4d9e commit 470c171
Show file tree
Hide file tree
Showing 24 changed files with 548 additions and 200 deletions.
19 changes: 19 additions & 0 deletions build/pkgs/pdf2svg/SPKG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pdf2svg - PDF to SVG convertor
==============================

Description
-----------

pdf2svg is a tiny command-line utility using Cairo and Poppler to convert PDF
documents into SVG files. Multi-page PDF can be split up to one SVG per page by
passing a file naming specification.

License
-------

GPL

Upstream Contact
----------------

http://cityinthesky.co.uk/opensource/pdf2svg/
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/alpine.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/arch.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/conda.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/cygwin.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/debian.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/fedora.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/freebsd.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
graphics/pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/homebrew.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/macports.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/nix.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/opensuse.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/repology.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/distros/void.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pdf2svg
5 changes: 5 additions & 0 deletions build/pkgs/pdf2svg/spkg-configure.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SAGE_SPKG_CONFIGURE([pdf2svg], [
AC_PATH_PROG([PDF2SVG], [pdf2svg])
AS_IF([test -z "$ac_cv_path_PDF2SVG"], [sage_spkg_install_pdf2svg=yes])
])

1 change: 1 addition & 0 deletions build/pkgs/pdf2svg/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
optional
91 changes: 76 additions & 15 deletions src/sage/doctest/external.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def has_internet():
EXAMPLES::
sage: from sage.doctest.external import has_internet
sage: has_internet() # random, optional -- internet
sage: has_internet() # random, optional -- internet
FeatureTestResult('internet', True)
"""
from sage.features.internet import Internet
Expand All @@ -62,20 +62,50 @@ def has_latex():
EXAMPLES::
sage: from sage.doctest.external import has_latex
sage: has_latex() # random, optional - latex
True
sage: has_latex() # optional - latex
FeatureTestResult('latex', True)
"""
from sage.misc.latex import _run_latex_, _latex_file_
from sage.misc.temporary_file import tmp_filename
try:
f = tmp_filename(ext='.tex')
O = open(f, 'w')
O.write(_latex_file_('2+3'))
O.close()
_run_latex_(f)
return True
except Exception:
return False
from sage.features.latex import latex
return latex().is_present()

def has_xelatex():
"""
Test if xelatex is available.
EXAMPLES::
sage: from sage.doctest.external import has_xelatex
sage: has_xelatex() # optional - xelatex
FeatureTestResult('xelatex', True)
"""
from sage.features.latex import xelatex
return xelatex().is_present()

def has_pdflatex():
"""
Test if pdflatex is available.
EXAMPLES::
sage: from sage.doctest.external import has_pdflatex
sage: has_pdflatex() # optional - pdflatex
FeatureTestResult('pdflatex', True)
"""
from sage.features.latex import pdflatex
return pdflatex().is_present()

def has_lualatex():
"""
Test if lualatex is available.
EXAMPLES::
sage: from sage.doctest.external import has_lualatex
sage: has_lualatex() # optional - lualatex
FeatureTestResult('lualatex', True)
"""
from sage.features.latex import lualatex
return lualatex().is_present()

def has_magma():
"""
Expand Down Expand Up @@ -274,6 +304,32 @@ def has_imagemagick():
from sage.features.imagemagick import ImageMagick
return ImageMagick().is_present()

def has_dvipng():
"""
Test if dvipng is available.
EXAMPLES::
sage: from sage.doctest.external import has_dvipng
sage: has_dvipng() # optional -- dvipng
FeatureTestResult('dvipng', True)
"""
from sage.features.dvipng import dvipng
return dvipng().is_present()

def has_pdf2svg():
"""
Test if pdf2svg is available.
EXAMPLES::
sage: from sage.doctest.external import has_pdf2svg
sage: has_pdf2svg() # optional -- pdf2svg
FeatureTestResult('pdf2svg', True)
"""
from sage.features.pdf2svg import pdf2svg
return pdf2svg().is_present()

def has_rubiks():
"""
Test if the rubiks package (``cu2``, ``cubex``, ``dikcube``,
Expand Down Expand Up @@ -345,21 +401,26 @@ class AvailableSoftware(object):
sage: external_software
['4ti2',
'cplex',
'dvipng',
'ffmpeg',
'graphviz',
'gurobi',
'imagemagick',
'internet',
'latex',
'lualatex',
'macaulay2',
'magma',
'maple',
'mathematica',
'matlab',
'octave',
'pandoc',
'pdf2svg',
'pdflatex',
'rubiks',
'scilab']
'scilab',
'xelatex']
sage: 'internet' in available_software # random, optional - internet
True
sage: available_software.issuperset(set(['internet','latex'])) # random, optional - internet latex
Expand Down
36 changes: 36 additions & 0 deletions src/sage/features/dvipng.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
r"""
Check for dvipng
"""
# ****************************************************************************
# Copyright (C) 2021 Sebastien Labbe <slabqc@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# https://www.gnu.org/licenses/
# ****************************************************************************

from . import Executable

class dvipng(Executable):
r"""
A :class:`sage.features.Feature` describing the presence of ``dvipng``
EXAMPLES::
sage: from sage.features.dvipng import dvipng
sage: dvipng().is_present() # optional: dvipng
FeatureTestResult('dvipng', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.dvipng import dvipng
sage: isinstance(dvipng(), dvipng)
True
"""
Executable.__init__(self, "dvipng", executable="dvipng",
url="https://savannah.nongnu.org/projects/dvipng/")
138 changes: 138 additions & 0 deletions src/sage/features/latex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-
r"""
Check for pdflatex and equivalent programs
"""
# ****************************************************************************
# Copyright (C) 2021 Sebastien Labbe <slabqc@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# https://www.gnu.org/licenses/
# ****************************************************************************

from . import Executable, FeatureTestResult

class latex(Executable):
r"""
A :class:`sage.features.Feature` describing the presence of ``latex``
EXAMPLES::
sage: from sage.features.latex import latex
sage: latex().is_present() # optional: latex
FeatureTestResult('latex', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.latex import latex
sage: isinstance(latex(), latex)
True
"""
Executable.__init__(self, "latex", executable="latex",
url="https://www.latex-project.org/")

def is_functional(self):
r"""
Return whether `latex` in the path is functional.
EXAMPLES:
sage: from sage.features.latex import latex
sage: latex().is_functional() # optional: latex
FeatureTestResult('latex', True)
"""
lines = []
lines.append(r"\documentclass{article}")
lines.append(r"\begin{document}")
lines.append(r"$\alpha+2$")
lines.append(r"\end{document}")
content = '\n'.join(lines)

# create a simple tex file with the content
from sage.misc.temporary_file import tmp_filename
base_filename_tex = tmp_filename(ext='.tex')
with open(base_filename_tex, 'w') as f:
f.write(content)
import os
base, filename_tex = os.path.split(base_filename_tex)

# running latex
from subprocess import run
cmd = ['latex', '-interaction=nonstopmode', filename_tex]
cmd = ' '.join(cmd)
result = run(cmd, shell=True, cwd=base, capture_output=True, text=True)

# return
if result.returncode == 0:
return FeatureTestResult(self, True)
else:
return FeatureTestResult(self, False, reason="Running latex on "
"a sample file returned non-zero "
"exit status {}".format(result.returncode))

class pdflatex(Executable):
r"""
A :class:`sage.features.Feature` describing the presence of ``pdflatex``
EXAMPLES::
sage: from sage.features.latex import pdflatex
sage: pdflatex().is_present() # optional: pdflatex
FeatureTestResult('pdflatex', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.latex import pdflatex
sage: isinstance(pdflatex(), pdflatex)
True
"""
Executable.__init__(self, "pdflatex", executable="pdflatex",
url="https://www.latex-project.org/")

class xelatex(Executable):
r"""
A :class:`sage.features.Feature` describing the presence of ``xelatex``
EXAMPLES::
sage: from sage.features.latex import xelatex
sage: xelatex().is_present() # optional: xelatex
FeatureTestResult('xelatex', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.latex import xelatex
sage: isinstance(xelatex(), xelatex)
True
"""
Executable.__init__(self, "xelatex", executable="xelatex",
url="https://www.latex-project.org/")

class lualatex(Executable):
r"""
A :class:`sage.features.Feature` describing the presence of ``lualatex``
EXAMPLES::
sage: from sage.features.latex import lualatex
sage: lualatex().is_present() # optional: lualatex
FeatureTestResult('lualatex', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.latex import lualatex
sage: isinstance(lualatex(), lualatex)
True
"""
Executable.__init__(self, "lualatex", executable="lualatex",
url="https://www.latex-project.org/")
Loading

0 comments on commit 470c171

Please sign in to comment.