- daniel-aaaabO5Djy@demonhorse.com
- 503-913-9333
Yanki is a Python command line tool made to simplify creating thousands of video flashcards from YouTube videos.
I initially wrote Yanki to be just an authoring tool to produce flashcards for the popular Anki app, but it turned out that my classmates had trouble using the app. To make it useful to them, I updated Yanki to produce static HTML that can be hosted on any web server (demo).
Internally, Yanki includes a simple parser for deck definition files, and uses ffmpeg to trim, crop, and/or slow video. Since ffmpeg is primarily single threaded when encoding media, Yanki uses Python’s asyncio
to run multiple instance in parallel and significantly cut down the time needed to process thousands of flashcards.
I configure my shell prompt to display information about the current git repository, e.g. the name of the curent branch, whether or not there are uncommitted changes, etc. Loading that information required multiple calls to Htmlize is a Rust crate that correctly encodes and decodes HTML text.git-status-vars — github.com/danielparks/git-status-vars
✔ better-timeout ○ ↑1 ~/projects/git-status-vars 8:58:24 PM
❯ eval $(time git-status-vars)
0.02s elapsed 80% CPU
✔ better-timeout ○ ↑1 ~/projects/git-status-vars 8:58:31 PM 0.1s
❯ echo $head_ref1_short ↑$head_ahead unstaged: $unstaged_count
better-timeout ↑1 unstaged: 3
git
which added a noticeable delay after every command, including trivial ones like cd
. Git-status-vars uses libgit2
to quickly read common repo information, then prints the information in shell variable form. The output can be eval
ed and the variables can be used in a prompt.htmlize — github.com/danielparks/htmlize
assert!(htmlize::escape_attribute("1 & 2 < 3")
== "1 & 2 < 3");
assert!(htmlize::unescape("3 × 4 > 10")
== "3 × 4 > 10");
Encoding entities is easy and fast, but decoding entities correctly has two major edge cases: not all entities have to end with a semicolon, e.g. ©
(©), and some entities contain other entities as a prefix, e.g. ℗
(℗).
After significant experimentation, I chose two fast decode algorithms. They produce identical results, but switching between them trades faster compile times (with a perfect hash) for faster run times (with a massive match
tree generated by my crate matchgen).
In Rust, the fastest way to match the next substring from a limited set of strings is to use a tree of match
statements. Matchgen makes that easy.
matchgen::TreeMatcher::new("pub fn decode", "u8") .doc("Decode basic HTML entities.") .add(b"&", "b'&'") .add(b"<", "b'<'") .add(b">", "b'>'") .add(b""", "b'\"'") .write_to_out_dir("decoder.rs")?;
Simple yet flexible Go installations with Puppet.
class { 'golang': ensure => latest, }
Armature is a tool for deploying Puppet environments and modules. It sets up Puppet environments for each branch in your control repo and installs modules as specified by the Puppetfile for each environment.
❯ armature deploy-branches my-puppet-code.git '*'
Armature is designed to replace r10k for certain, very specific use cases. It does not have nearly as many features, but it is much faster.