Phil's Musings notes from a peripatetic programmer

Recent Posts


CSS Diffs

Our textbooks are frequently hundreds of pages long and use a single CSS file, so making a CSS change can change content in unexpected places.

Again, CSS Polyfills and a little XSLT file makes this easy.

CSS-Diff takes an HTML and CSS file and produces an HTML file with all the styling “baked” in. Then, the provided XSLT file can compare 2 “baked” HTML files and inject <span> tags whenever the styles differ.

See the CSS-Diff project to run it from the commandline.

Keep Reading...

css-polyfills.js do more with CSS!

I often hear “CSS is meant to style and HTML should describe content”, but CSS alone is not enough to make textbooks.

Sometimes you need to:

  1. style an element based on what’s inside (notes containing a title)
  2. change link text based on the target (See Figure 2a vs See Table 4.3)
  3. move elements somewhere else in the book (answers to the back)

Well, now there is css-polyfills.js, based on some great CSS3 specs, Sizzle, and selector-set.

Simple Examples (from Bootstrap)

With css-polyfills.js you can do things that are not possible using CSS in browsers. Bootstrap’s Dismissable Alerts require adding a special class on the alert if it contains a close button. This can be accomplished without adding the alert-dismissable class by using :has:

.alert:has(> .close) { /* Styles for `.alert-dismissable` */ }

Bootstrap Modals and Input Groups require adding wrapper elements in order to style properly; with nested ::before and ::outside these are unnecessary.

You can construct the 2 additional elements (.modal, .modal-dialog) around .modal-content using the following CSS:

.modal-content                  { ... }
.modal-content::outside         { /* Styles for `.modal-dialog` */}
.modal-content::outside::outside{ /* Styles for `.modal` */ }

More Examples

You can even style links depending on the target:

a[href^="#"] {
  // Use target-is as a guard for which link text to use
  content: target-is(attr(href), 'figure')   'See Figure';
  content: target-is(attr(href), 'table')    'See Table';
  content: target-is(attr(href), '.example') 'See Example';

Or, you can move elements down the page (ie collate footnotes at the bottom of a wikipedia article):

.footnote { move-to: footnotes-area; }
#footnotes {
  content: pending(footnotes-area);

You can also create the linkable footnotes on wikipedia by keeping the references near the content and use CSS to create links and move the references to the bottom of the page (See Clickable Footnotes).

Of course, there’s much more that can be accomplished using css-polyfills.js; check the for more details.

Keep Reading...

CSS Coverage for Javascript Unit Tests

There are many CSS coverage projects but none plug directly into JS unit tests, instrumenting at the same time as the JavaScript coverage.

Assuming you have BlanketJS and Mocha tests, just grab css-coverage.js and add the following into the test harness HTML file :

<link rel="stylesheet/coverage" href="path/to/file.less" />
<script src="css-coverage.js"></script>

Less.js + Mocha + BlanketJS

The coverage script uses the less.tree AST to parse all the selectors and the debugInfo data to get line numbers. It adds a testdone hook to Mocha that runs all the selectors on the page. Then, the line number and coverage counts are given to BlanketJS so LESS/CSS files are included in the coverage report.

Example Screenshot

CSS Coverage Demo

Check out the Mocha + BlanketJS demo and the github repo for more!

Other Features

  • Loading LESS files using RequireJS is supported with 0 additional work
  • Instrumented less files that import other files are automatically instrumented
Keep Reading...

Building an eBook using GitHub

At Connexions we build free textbooks. To do it we have roughly 4 services:

  • Published Repository (Published Books)
  • Authoring Repository (Drafts)
  • Generate exports (EPUB, PDF)
  • Website

As someone who uses GitHub and Travis daily, I wondered how much of this GitHub (and Travis) can do for us. It turns out, quite a bit. If each book is a repository whose contents is an Unzipped EPUB then amazing things are possible.

Book Publishing = GitHub Repo + GitHub Pages + “Download as Zip” + Service Hooks

  • the master branch is the published version of the book
  • tags are various editions of a book
  • gh-pages branch can be used as a book reader (Website)
  • “Download as Zip” is the EPUB version of the book
  • The editor can “save” via the GitHub API
  • Travis-CI can be used to generate a PDF (and “push” to AWS or some other place)

So, I took our editor and made it save EPUB files to GitHub and viola, a book editor using GitHub!

Keep Reading...

Introducing octokit.js

octokit.js is a JavaScript client that interacts with GitHub using their API. Try it out with the interactive demo!

Some unique features:

  • works in a browser or in NodeJS
  • uses Promises
  • written in CoffeeScript
  • Mocha unit tests that actually talk to GitHub (and run in the browser or commandline)
  • Code Coverage using BlanketJS (that runs in the browser or commandline)
  • supports Harmony Generators

API Support:

  • all repo operations (including create/remove)
  • Teams, Organizations, and Permissions
  • eTags for caching results
  • Notifications for rate limit changes
  • Committing multiple files at once

Finding a test and coverage framework that works both in a browser and on the commandline was a bit challenging but I’ll return to that in another post.

This library also uses jQuery.ajax and jQuery.Deferred.

Keep Reading...