Let's try scraping the example asymptote files from the Asymptote gallery and compiling and displaying them locally in this notebook.
Each of the example asymptote code files is linked from the html page http://asymptote.sourceforge.net/gallery/.index1.html. Using the python built-in libraries urllib2 and HTMLParser, we can request this page and read all of the links which point to .asy extension pages.
import urllib2
import HTMLParser
class AsyLinkParser(HTMLParser.HTMLParser):
def handle_starttag(self, tag, attrs):
if not hasattr(self, "asy_files"):
self.asy_files = []
if tag == "a":
for attr in attrs:
if attr[0] == "href" and attr[1].endswith(".asy"):
self.asy_files.append(attr[1])
gallery_url_base = "http://asymptote.sourceforge.net/gallery/"
parser = AsyLinkParser()
parser.feed(urllib2.urlopen(gallery_url_base + ".index1.html").read())
parser.asy_files[:10]
['pdb.asy', 'BezierPatch.asy', 'BezierSurface.asy', 'CAD1.asy', 'CDlabel.asy', 'Coons.asy', 'GaussianSurface.asy', 'Gouraud.asy', 'Hobbycontrol.asy', 'Hobbydir.asy']
Unfortunately a few of the examples are missing and a few of the examples do not compile locally under my current minimal configurations, for example due to missing asymptote modules. Also, some of the examples explicitly set themselves to save to particular output image filenames or formats, instead of the temporary file locations that the ipython-asymptote module expects. Let's skip over these troublesome examples.
asy_data = []
skip_urls = ["intro.asy", # This file is missing
"exp3.asy", # Compiling leads to a stack overflow?
"galleon.asy", # Requires external data
"westnile.asy", # Requires external data
]
# These keywords suggest additional asymptote modules or tampering
# with settings in an unexpected way.
skip_list = ["cpkcolors", "embed", "logo", "settings"]
for gallery_url in parser.asy_files:
if gallery_url in skip_urls:
continue
asy_code = urllib2.urlopen(gallery_url_base + gallery_url).read()
if not any([skip_word in asy_code for skip_word in skip_list]):
asy_data.append({"code": asy_code, "name": gallery_url})
Since there are a lot of examples in the Asymptote gallery:
len(asy_data)
172
Let's write a quick helper function to display just a subset of the images.
from IPython.display import display, HTML
import asymptote
def display_asy(asy_data, start_index=0, end_index=-1):
"""Display subset of asymptote examples"""
asy_codes = [tup["code"] for tup in asy_data[start_index : end_index]]
with asymptote.TemporaryAsymptoteFile(asy_codes) as tmp_asy:
for i, asy_file in enumerate(tmp_asy.asy_files):
display(HTML("<a href='{base}/{asy}'>{asy}</a>".format(
base=gallery_url_base, asy=asy_data[i + start_index]["name"])))
display(asymptote.run_asy_file(asy_file)[0])
asymptote.TemporaryAsymptoteFile
creates a temporary location to save the asy codes and asymptote.run_asy_files
compiles the asy codes and returns the output image.
Let's compile and display everything now!
display_asy(asy_data, 0, 10)
display_asy(asy_data, 10, 20)
display_asy(asy_data, 20, 30)
display_asy(asy_data, 30, 40)
display_asy(asy_data, 40, 50)
The idea should be pretty clear by now. We wrap up by compiling and displaying the last 10 asymptote examples in the gallery.
display_asy(asy_data, -10, -1)