Mozilla just announced their Pyodide project, built with WebAssembly and emscripten:
Pyodide gives you a full, standard Python interpreter that runs entirely in the browser, with full access to the browser’s Web APIs.
WebAssembly has a lot of potential. I’m excited to see where it goes.
Good post on ownership in Rust, using Python as an example.
Came across Joel Grus’s I Don’t Like Notebooks slides on the downsides of Jupyter notebooks. I don’t really use Jupyter (other than when a class I recently took required it), but these are good points.
Came across a great tip on Python multiline strings using textwrap.dedent (so you don’t have to dedent everything in your code).
I’m pleased to announce version 2.0 of my Book of Mormon study edition.
This version now uses the licensed text of the scriptures from the Church, which means I’m finally able to make editions in other languages. To start out, we’ve got French, German, Italian, Portuguese, and of course Spanish.
To make it easier to create versions of the study edition in other languages, I started over from scratch, using a set of Python scripts to pull the text from the files the Church sent me, then generate a LaTeX document that gets turned into the PDF. It’s a really nice workflow.
Over the next month or so I’ll be revising several of my other scriptures projects (reader’s edition, Words of the Prophets, etc.) to use the licensed text, with a similar Python-based workflow to make updates easier.
Also, if you’re interested in a study edition in a new language, let me know.
I wrote the circle chording code on my phone in Pythonista, then ported it to PlotDevice, fleshed it out, and textured it in Photoshop.
I’ve renamed inkpdf to Press (as in printing press).
I reached the point where creating the PDF manually is no longer feasible, so I’ve been working on getting Press to a point where I can implement the PDF generation. The basic structure is in place, sans the PDF part. (That’s next.)
Here’s what a Press script looks like right now:
from press import Press p = Press('output.pdf', width=6*Press.INCH, height=11*Press.INCH, margin=1*Press.INCH) # Horizontal borders at top and bottom of page p.stroke('#000') p.pen(1.0) p.line(p.page_min_x, p.page_min_y, p.page_max_x, p.page_min_y) p.line(p.page_max_x, p.page_min_y, p.page_max_x, p.page_max_y) # Page 2 p.page(2) p.layer('base') p.stroke(rgb=(1, 0, 0)) p.line(150, 150, 300, 300) p.layer('fg') p.stroke(hsl=(0, 0.5, 0.8)) p.line(300, 300, 450, 150) # Go back and add another line to page 1 p.page(1) p.stroke('#025') p.line(p.page_min_x, p.page_min_y, p.page_min_x, p.page_max_y) p.save() # this doesn't work yet
You can also do something like this:
with Press('output2.pdf', size=Press.LETTER, margin=(0.5*Press.INCH, 1.0*Press.INCH), inner_margin=0.5*Press.INCH, outer_margin=1.25*Press.INCH, bleed=.125*Press.INCH) as p: p.line(50, 50, 250, 50) # And so on
(Context manager, inner/outer margin, bleed, built-in paper sizes.)
Up next: adding more primitives, designing the font selection mechanism, getting it to generate an actual PDF, embedding fonts, using arbitrary Unicode code points, integrating HarfBuzz, etc.
Lifter is “a lightweight query engine for Python iterables.” Looks nice. One of their examples:
# vanilla Python results = [ user for user in users if user['age'] == 26 and user['is_active'] ] # lifter results = manager.filter(User.age == 26, User.is_active == True)