Skip to content

Commit

Permalink
sagemathgh-38339: Add sage.misc.latex.pdf to save the image of object…
Browse files Browse the repository at this point in the history
…s to pdf

    
<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->

Hence
```sage
sage: from sage.misc.latex import pdf
sage: pdf(pi, 'test.pdf')
```
works. This is a companion to the existing `sage.misc.latex.png`, which
saves png image of objects. Of course, pdf image is scalable and hence
more suitable for inclusion into latex documents.

Also we fix it that `view()` sporadically fails on mac because the
temporary file is removed before the viewer opens the file. For example,
```sage
sage: view(pi)  # show pi
```
Thus after this PR, the temporary file is removed when the viewer
(`Preview` app on mac, not the window showing the image) closes. This
behavior is consistent with that on linux.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#38339
Reported by: Kwankyu Lee
Reviewer(s): Dima Pasechnik
  • Loading branch information
Release Manager committed Oct 8, 2024
2 parents b0f09d9 + 841298f commit fb74d58
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 7 deletions.
84 changes: 78 additions & 6 deletions src/sage/misc/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,9 @@ def _latex_file_(objects, title='SAGE', debug=False,
s = LATEX_HEADER + '\n' + MACROS + s + '\n\\end{document}'

if debug:
print('----')
print(s)
print('----')

return s

Expand Down Expand Up @@ -1827,7 +1829,6 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False,
...
ValueError: Unsupported LaTeX engine.
"""

if tightpage:
if margin is None:
margin_str = ""
Expand Down Expand Up @@ -1870,16 +1871,16 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False,
tmp.cleanup()
return
output_file = os.path.join(tmp.name, "sage." + suffix)
# this should get changed if we switch the stuff in misc.viewer to
# producing lists

if debug:
print('viewer: "{}"'.format(viewer))
print(f'temporary file: "{output_file}"')
print(f'viewer: "{viewer}"')

# Return immediately but only clean up the temporary file after
# the viewer has closed. This function is synchronous and waits
# for the process to complete...
def run_viewer():
run([viewer, output_file], capture_output=True)
run([*viewer.split(), output_file], capture_output=True)
tmp.cleanup()

# ...but we execute it asynchronously so that view() completes
Expand All @@ -1890,7 +1891,78 @@ def run_viewer():
t.daemon = True
t.start()

return

def pdf(x, filename, tiny=False, tightpage=True, margin=None, engine=None, debug=False):
"""
Create an image from the latex representation of ``x`` and save it as a pdf
file with the given filename.
INPUT:
- ``x`` -- a Sage object
- ``filename`` -- the filename with which to save the image
- ``tiny`` -- boolean (default: ``False``); if ``True``, use a tiny font
- ``tightpage`` -- boolean (default: ``True``); use the LaTeX package
``preview`` with the 'tightpage' option
- ``margin`` -- float (default: no margin); width of border, only effective
with 'tight page'
- ``engine`` -- (default: ``None``) ``'latex'``, ``'pdflatex'``,
``'xelatex'`` or ``'lualatex'``; if ``None``, the value defined in the
LaTeX global preferences ``latex.engine()`` is used
- ``debug`` -- boolean (default: ``False``); if ``True``, print verbose output
EXAMPLES::
sage: # optional - latex
sage: from sage.misc.latex import pdf
sage: import tempfile
sage: with tempfile.NamedTemporaryFile(suffix=".pdf") as f: # random
....: pdf(ZZ[x], f.name)
"""
from sage.plot.graphics import Graphics
if isinstance(x, Graphics):
x.save(filename)
return

if tightpage:
if margin is None:
margin_str = ""
else:
margin_str = '\n\\setlength\\PreviewBorder{%fmm}' % margin
latex_options = {'extra_preamble':
'\\usepackage[tightpage,active]{preview}\n' +
'\\PreviewEnvironment{page}%s' % margin_str,
'math_left': '\\begin{page}$',
'math_right': '$\\end{page}'}
else:
latex_options = {}

# create a string of latex code to write in a file
s = _latex_file_([x], title='', tiny=tiny, debug=debug, **latex_options)
if engine is None:
engine = _Latex_prefs._option["engine"]
# path name for permanent pdf output
abs_path_to_pdf = os.path.abspath(filename)
# temporary directory to store stuff
with TemporaryDirectory() as tmp:
tex_file = os.path.join(tmp, "sage.tex")
pdf_file = os.path.join(tmp, "sage.pdf")
# write latex string to file
with open(tex_file, 'w') as file:
file.write(s)
# run latex on the file
e = _run_latex_(tex_file, debug=debug, engine=engine)
if e == 'pdf':
# if no errors, copy pdf_file to the appropriate place
shutil.copy(pdf_file, abs_path_to_pdf)
else:
print("Latex error or no pdf was generated.")


def png(x, filename, density=150, debug=False,
Expand Down
2 changes: 1 addition & 1 deletion src/sage/misc/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def default_viewer(viewer=None):
elif os.uname()[0] == 'Darwin':
# Simple on OS X, since there is an open command that opens
# anything, using the user's preferences.
BROWSER = 'open'
BROWSER = 'open -W'
DVI_VIEWER = BROWSER
PDF_VIEWER = BROWSER
PNG_VIEWER = BROWSER
Expand Down

0 comments on commit fb74d58

Please sign in to comment.