From bcef6c6339823ec1d823af1246cfb26eec0f9b52 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 1 Sep 2019 19:43:33 -0400 Subject: [PATCH] Add the \sagelisting macro and associated machinery. --- GNUmakefile | 25 ++++++++++++++++++++++++- examples.tex | 10 +++++++++- mjo-listing.tex | 14 ++++++++++++++ sage_listings/example.listing | 2 ++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 sage_listings/example.listing diff --git a/GNUmakefile b/GNUmakefile index 78800b0..fba3b37 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -26,6 +26,11 @@ MJOTEX += mjo-font.tex mjo-linear_algebra.tex mjo-listing.tex mjo-misc.tex MJOTEX += mjo-proof_by_cases.tex mjo-theorem.tex mjo-theorem-star.tex MJOTEX += mjo-topology.tex mjo.bst +# Compile a list of raw source code listings (*.listing) and their +# associated output files (*.py) that will be tested by check-sage. +SAGE_LISTING_SRCS = $(wildcard sage_listings/*.listing) +SAGE_LISTING_DSTS = $(patsubst %.listing,%.py,$(SAGE_LISTING_SRCS)) + # Use kpsewhich (from the kpathsea suite) to find the absolute paths # of the bibtex/mjotex files listed in in $(BIBS)/$(MJOTEX). The SRCS # variable should contain all (Bib)TeX source files for the document. @@ -130,6 +135,11 @@ $(PN).log: $(SRCS) $(MAKE) clean $(MAKE) +# How do we convert a raw listing into something testable by sage? We +# append/prepend triple quotes to make the whole thing into a doctest. +sage_listings/%.py: sage_listings/%.listing + echo '"""' > $@ && cat $< >> $@ && echo '"""' >> $@ + # Ensure that there are no overfull or underfull boxes in the output # document by parsing the log for said warnings. .PHONY: check-boxes @@ -149,9 +159,21 @@ check-chktex: check-undefined: $(PN).log @! grep -i 'undefined' $< +# Use sage to doctest any \sagelisting{}s in SAGE_LISTING_DSTS. +# The actuall command is ifdef'd so that we can comment out +# the definition of SAGE_LISTING_DSTS without breaking the +# default definition of the "check" target. +.PHONY: check-sage +check-sage: $(SAGE_LISTING_DSTS) +ifdef SAGE_LISTING_DSTS + PYTHONPATH="$(HOME)/src/sage.d" \ + sage -t --timeout=0 --memlimit=0 \ + $^ +endif + # Run a suite of checks. .PHONY: check -check: check-boxes check-chktex check-undefined +check: check-boxes check-chktex check-undefined check-sage # Clean up leftover junk. This only looks overcomplicated because # the *.{foo,bar} syntax supported by Bash is not POSIX, and Make @@ -162,6 +184,7 @@ JUNK_EXTENSIONS += snm spl toc xml clean: for ext in $(JUNK_EXTENSIONS); do rm -f *.$$ext; done; rm -rf dist/ + rm -f $(SAGE_LISTING_DSTS) # If this document will be published, the publisher isn't going to # have your BibTeX database or your mjotex files. So, you need to diff --git a/examples.tex b/examples.tex index a43b26e..b6c4ae1 100644 --- a/examples.tex +++ b/examples.tex @@ -168,7 +168,7 @@ \end{section} \begin{section}{Listing} - Here's an interactive sage prompt: + Here's an interactive SageMath prompt: \begin{tcblisting}{listing only, colback=codebg, @@ -181,6 +181,14 @@ [0 0], [0 0], [1 0], [0 1] ] \end{tcblisting} + + However, the smart way to display a SageMath listing is to load it + from an external file (under the ``listings'' subdirectory): + + \sagelisting{example} + + Keeping the listings in separate files makes it easy for the build + system to test them. \end{section} \begin{section}{Miscellaneous} diff --git a/mjo-listing.tex b/mjo-listing.tex index 5207aa2..f733be6 100644 --- a/mjo-listing.tex +++ b/mjo-listing.tex @@ -38,3 +38,17 @@ keywordstyle=\color{brilliantlavender}, stringstyle=\color{brilliantgreen} } + + +% Input a SageMath example code listing from a file. You generally +% want these to be in separate files so that the build system can test +% them automatically. +% +% The sole argument is the "name" of the listing, which ultimately +% just identifies a file named "sage_listings/.listing". +\newcommand*{\sagelisting}[1]{\tcbinputlisting{listing only,% + colback=codebg,% + coltext=codefg,% + left=2em,% + listing options={language=sage,style=sage},% + listing file=sage_listings/#1.listing}} diff --git a/sage_listings/example.listing b/sage_listings/example.listing new file mode 100644 index 0000000..d475764 --- /dev/null +++ b/sage_listings/example.listing @@ -0,0 +1,2 @@ +sage: Cone([(1,0),(0,1)]).lyapunov_rank() +2 -- 2.43.2