Published

Make a PDF looked like a scanned doc using ImageMagick

You can make a PDF looked like a scanned document using ImageMagick. Useful for all the unfortunate orgs that still don’t accept electronic signatures and such.

Make sure you have ImageMagick installed and then run this on the command line:

convert -density 140 input.pdf -rotate "$([ $((RANDOM % 2)) -eq 1 ] && echo -)0.$(($RANDOM % 4 + 5))" -attenuate 0.1 +noise Multiplicative -flatten -attenuate 0.01 +noise Multiplicative -sharpen 0x1.0 -colorspace Gray output.pdf

Based on this Gist but with some tweaks based on my preferences.

Published

Where are the non-English programming languages? Thoughts prompted by a small but mighty bug

A short two-parter

Part 1: A small-but-mighty bug

I’m doing a few coding-for-designers workshops with the students in the MA Graphic Media Design programme at the LCC, the first one was this past Thursday.

We’re focusing on web stuff since that’s what they expressed the most interest in and it’s in my wheelhouse. We started with a broad and brief overview of code, about how we use human-readable programming languages to communicate with computers. But 99% of the time, when we say “human-readable” we really mean “English-based”. More on this later.

After my short intro, we put together a simple webpage with HTML and CSS. A few of the students ran in to a small-but-mighty bug that I’ve never encountered before.

We were working on a basic CSS rule set, something like:

body {
  background-color: linear-gradient(blue, pink);
}

And for one of the students, it just wasn’t working. I checked it a bunch of times, it was all typed perfectly. No missing spaces or characters, spelling was fine. VSCode indicated that the background-color declaration wasn’t finished, which seemed weird. I looked really closely at it and noticed that the semicolon seemed a little thinner than the others in the file.

Turns out that the student had typed a full-width semicolon (U+FF1B) instead of a semicolon (U+003B). The full-width semicolon is used in Chinese to “demarcate parallel structures in a paragraph”. Another student ran in to the same problem a few minutes later, using a full-width left curly bracket (U+FF5B) instead of a left curly bracket (U+007B).

I had asked them to type in a semicolon, to type in a curly bracket, and so they typed the characters the way they normally do in their native languages. Super understandable.

If you were just starting to learn what code is and how it works, I can’t imagine how hard it would be to debug this sort of language-based problem on your own.

Part 2: Where are the non-English programming languages?

Gretchen McCulloch wrote a very worthwhile Wired article titled “Coding Is for Everyone—as Long as You Speak English”. I feel like every programmer / dev should read it.

Programming doesn’t have to be English-centric. As McCulloch puts it:

The computer doesn’t care. The computer is already running an invisible program (a compiler) to translate your IF or <body> into the 1s and 0s that it functions in, and it would function just as effectively if we used a potato emoji 🥔 to stand for IF and the obscure 15th century Cyrillic symbol multiocular O ꙮ to stand for <body>.

How would we go about implementing non-English HTML tags? W3C has an FAQ on the topic where they state that “HTML or XHTML tags are all pre-defined (in English) and must remain that way if they are to be correctly recognized by user agents (eg. browsers).

Since browsers just implement the standards set by W3C (I’m pretty sure that’s right?), I’m guessing that W3C would have to approve it if we wanted native non-English HTML support. It seems like it would be a bit of a mountain to climb but if we take something like Wikipedia’s translation efforts as an example, surely there are tons of people out there that would help with translation?

Gonna keep an eye on this. Need to find a book or good article on the history of ALGOL.

Published

Using CSS, HTML, and maybe a little logic to display images with a consistent surface area

Every once in a while, I have to figure out how to display images on the web with a consistent surface area. It’s usually in relation to making a lot of logos with very different aspect ratios look evenly sized so that none of them stick out like a sore thumb.

I haven’t had to do this in a while but came across a tweet by Nick Sherman that prompted me to think about it again.

To achieve an evenly-sized group of images, you have to calculate a maximum width that is proportionate to the surface area you want. To do this, you need to be able to calculate a square root, you need the width and height of each original image, and all of your images need to be tightly cropped since extra negative space will throw things off visually.

In the past, I’ve achieved this with logic since vanilla CSS doesn’t currently support a sqrt() function (more on this later). I’ve usually used PHP since I tend to work with Kirby CMS pretty often.

The function in PHP:

function max_img_width($img_width, $img_height, $ideal_area) {
  $max_width = round($img_width * sqrt($ideal_area / ($img_width * $img_height)));
  echo $max_width;
}

And the function in use + corresponding HTML:

<img style="max-width: <?php max_img_width(1500, 3000, 40000); ?>px;" src="https://piperhaywood.com/my-image.jpg">

A CSS-only solution that works now

There seems to be a CSS-only way to go about this though. Apparently you can approximate square roots in CSS by using a series of CSS variables and calc(), see more info in this thread.

Here’s the CSS and the image markup:

img {
  --width: 0;
  --height: 0;
  --ideal-area: 40000;
  --area: calc(var(--width) * var(--height));
  --ratio: calc(var(--ideal-area) / var(--area));
  --guess01: calc(calc(var(--ratio) + calc( var(--ratio) / var(--ratio))) / 2);
  --guess02: calc(calc(var(--guess01) + calc( var(--ratio) / var(--guess01))) / 2);
  --guess03: calc(calc(var(--guess02) + calc( var(--ratio) / var(--guess02))) / 2);
  --guess04: calc(calc(var(--guess03) + calc( var(--ratio) / var(--guess03))) / 2);
  --guess05: calc(calc(var(--guess04) + calc( var(--ratio) / var(--guess04))) / 2);
  --guess06: calc(calc(var(--guess05) + calc( var(--ratio) / var(--guess05))) / 2);
  --guess07: calc(calc(var(--guess06) + calc( var(--ratio) / var(--guess06))) / 2);
  --guess08: calc(calc(var(--guess07) + calc( var(--ratio) / var(--guess07))) / 2);
  max-width: calc(var(--width) * var(--guess08) / 2 * 1px);
}
<img style="--width: 1500; --height: 3000;" src="https://piperhaywood.com/my-image.jpg">

I’d want to do some more browser testing since this results in a pretty gnarly calc() situation by --guess08, but at first glance this seems like it might be a worthwhile solution. It doesn’t give us exactly proportionate surface areas but it gets very close. It only starts to fall apart with super skyscraper-y and letterbox-y images.

A few quick notes regarding why this is written as it is and ways that it could be tweaked:

I capped the number of guesses at eight because any more seemed to just fail, Chrome and Safari wouldn’t interpret such a big calc() equation.

I set the default width and height to zero so that there is no max width restriction if the image tag is missing the width and height CSS variables. This could be changed, as could the ideal area variable (increase to get larger images, decrease to get smaller).

The 1px value in the max-width calculation is required so that the value is interpreted as a unit. That said, it doesn’t have to be pixels! Could change this to another unit like 1em or 1%.

If I wanted to display these evenly centred, I’d probably give the images some margin and then wrap them in a container with styles as below:

.container {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

Could also use CSS grid for a more consistent spacing result.

And a final reminder: this only visually scales the images. Try to avoid loading a 3000px wide image if you’re going to be displaying it around 200px wide, your users and the planet will thank you.

A CSS-only solution that might work in the future

So apparently more complex math functions including sqrt() might be coming to CSS in the future! See this issue raised by Lea Verou in the CSS specifications editor’s drafts repo and the exponential functions section from CSS Values and Units Module Level 4 in the W3C editor’s draft from 3 February 2020 (a couple days ago!).

I’m not sure when this would become part of the spec and no idea if / when the browsers might implement them, but here is a snippet that should work with that new function in theory:

img {
  --width: 0;
  --height: 0;
  --ideal-area: 40000;
  max-width: calc(var(--width) * sqrt(calc(var(--ideal-area) / calc(var(--width) * var(--height)))) / 2 * 1px);
}

I’m happy that Nick asked the question on Twitter, I actually need this on an upcoming project where I’ve only got Twig to work with which doesn’t support square roots, and I’d prefer to avoid JavaScript in this instance. Hopefully this is the solution, will update here if so.

A picture says a thousand words, so see Nick’s very nice demo of area-based image sizing with CSS to check out one possible outcome.


Edit 05.02.20

Edited a few words for clarity, added Nick’s demo, added future example incorporating a CSS-based sqrt() function.

Thanks Sam Baldwin for bringing future math function support in CSS to my attention!

Edit 06.02.20

Simplified the PHP + HTML example.

The original PHP + HTML example used a --max-width CSS variable instead of just applying a max-width directly. I used a CSS variable because I thought that they were compliant with a strict Content Security Policy that includes the style-src directive set to unsafe-inline. That assumption was incorrect, though there does seem to be some discussion about the topic.

Thanks Lizzie Malcolm for questioning the CSS var usage in the PHP example!

Edit 18.02.20

Changed parenthesis-enclosed arithmetic so that each is enclosed in calc(). Plain CSS seems to interpret arithmetic enclosed in parenthesis just fine, but SASS doesn’t seem to like it.

Published

Selecting open, free, or commons licenses for content and code

Content and code licensing is a bit of a minefield.

The first thing to remember is that in the UK and USA at least, all creative works are automatically protected by copyright from the moment they are made. The creator retains exclusive rights to their work, and nobody can share, copy, or use the work without the creator’s direct permission unless they are sharing it in fair use (critique, comment, parody, etc.). This is the reasoning behind the classic “all rights reserved” statement you often see in relation to a creative work.

Cover of “Copy This Book” by Eric Schrijver

But it is foolish to believe that “all rights reserved” will always be respected for content online. Tumblr and other platforms have made it so effortless to share others’ work that the public perception of copyright is seriously warped. Creators are very welcome to reserve their rights to all of their work but if they’re releasing it online under such terms, they should be prepared for a lot of violations.

The nature of the Internet created a need for less restrictive copyright licenses, and a whole host of open, free, and commons licenses have filled the void. This is my experience navigating the space for my own work including some of the resources I’ve used, the licenses I have chosen, and my reasoning.

Continue reading

Published

gemmacope.land

gemmacope.land

Gemma Copeland’s new site is online! This was really fun, one of the truest collaborations I’ve done in a while. Minimal JavaScript, Eleventy + Netlify, Arena API fun, unicode arrows, accessibility at the fore. It was an exercise in playful sufficiency, hopefully we’ve created a functional sandbox that she can work with for some years to come.

I’m hoping to write a bit more about the development at some point, particularly on working with the Arena API. Ran in to some interesting hurdles with block ordering! In the meantime, see the repository on GitHub and check out the making-of post on her website.

Published

Enabling Imagick extension with Laravel Valet

After setting up Laravel Valet and MySQL with Homebrew a while ago, local development has been pretty smooth sailing. Today though, I ran in to some trouble getting the Imagick extension up and running. After some searching online, this discussion thread got me going in the right direction.

I had Homebrew and pkg-config installed already, so the first thing I did was install ImageMagick with Homebrew by running brew install imagick. Next, I installed the Imagick extension with PECL by running pecl install imagick. It’s worth keeping an eye on the output related to this installation. At the very end of the output, I got this error:

ERROR: failed to mkdir /usr/local/Cellar/php@7.2/7.2.19_1/pecl/20170718

Someone else in the discussion thread ran in to a similar problem, so I roughly followed their directions. I ran pecl config-get ext_dir to get the extensions directory that the PECL config expects, then I copied that output and ran mkdir -p . I then ran pecl install imagick again, and this time there were no errors. Note that the output from this successful installation ended in Extension imagick enabled in php.ini.

To wrap it all up, I ran valet restart and then ran php -i | grep Imagick to check that Imagick Imagick in the PHP configuration. It returned a few lines in relation to classes and the ImageMagick version indicating that everything is set up as necessary.

Note that this only applies to the PHP version that is currently in use by Valet. I use a few different versions depending on the project, so I’ve repeated the pecl install imagick step for each of those versions as well.

Published

Notes from Redecentralize 2019

Been a busy few days with Redecentralize on Friday followed by MozFest over the weekend. Redecentralize was a one-day unconference at 4th Floor Studios in Whitechapel. The event was expertly organised by Ira Bolychevsky and her crack team.

It was a day of thought-provoking conversations and notebook scribbling. This is an attempt to decode the scribbles, make some follow-up plans, and to generally summarise the day from my perspective. There was a lot going on so I can’t cover it all, but I’m going to keep an eye out for other people’s notes via the Redecentralize newsletter.

\              \                      \                   \
\\\   \   \    \\            \        \\       \       \  \\
\\\\\ \\\ \\\  \\\   \    \  \\     \ \\\  \   \\  \   \\ \\\ \
\\ \\\\\\\\\\\ \\\\ \\\\  \\\\\\   \\\\\\\\\\\ \\\ \\\ \\\\\\\\
\\   \\\  \\\\\\\ \\\\\\\\\\\\\\\\\\\\\\ \\ \\\\\\\\\\\\\\\\  \
 \     \    \\  \   \    \\\  \  \\\   \  \   \\\ \\\ \\\  \   
              \            \       \            \   \   \

Read more

Published

Webmentions up and running

Finally sorted out how comments and webmentions are displayed on this site. It was kind of a hefty task since it involved sorting out WordPress comments as well. If everything works as intended (big if), webmentions should be displayed in a discussion thread below the post contents on permalink pages regardless of whether or not WordPress comments are enabled on that post. We’ll see how that goes!

As an experiment, I’ve turned on comments here, here, and on this note. Overall though, I’ll probably leave them disabled for the majority of my notes. This 2013 article by Kartik Prabhu sums up my feelings on the subject pretty well.

Published

Configuring and troubleshooting Netlify Large Media

Sam and I were working together to debug some issues encountered while configuring Netlify Large Media for a particular repository. It’s a *very* cool option when it comes to media for static site generators, particularly since it allows you to transform images. This is a run-down of the process, including a few specific snags we hit along the way.

Read more