15 years of tweets
Read all most of the nonsense here: https://macblaze.ca/?cat=9
Note: Since Elon’s take over, the removal of api’s and the subsequent X thing, my digest stopped working on May 11, 2023. So while I actually managed to stay on Twitter (X) for 15 years the tweets for the last 7 months have gone unrecorded. It might also be time to blow this joint. Although I will say that since all the hardcore Twitter users abandoned it it has been a much happier place (if you avoid the idjuts…).
BruceKeith is alive and well and living on Twitter. We’ll see how this goes…
Python in Ebook Production
The following is a blog post I originally wrote on behalf of Orca Book Publishers for the APLN (Accessible Publishing Learning Network) website. I had done a brief online Q&A on behalf of eBound talking about our Benetech certification and there were questions about my python workflow. So I tried to write it out, which was a good exercise in and of itself.
In 2022 Orca Book Publishers had a dozen accessible titles that had been remediated via programs with BooksBC and eBound as well as another group that had been created as mostly accessible epubs by outsourced ebook developers. When Orca made a commitment to creating accessibility ebooks the immediate goal was to pursue Benetech Certification with an eye to adopting a born accessible workflow and to start remediating backlist titles.
Orca has three main streams of books from an epub point of view: highly illustrated non-fiction, fiction with few or no images, and picture books. We started by remediating the fiction titles that were already mostly accessible and bringing them up to Benetech standards.
Concurrently we brought the non-fiction production in-house to begin to develop a functional accessible workflow. Non-fiction titles usually feature 80 plus illustrations and photographs, multiple sidebars, a glossary, index, and a bibliography.
In publishing circles a fair amount of time is spent bemoaning the shortcomings of InDesign as a platform for creating good epubs, let alone making accessible ones. With a complex design, you can spend a lot of time and effort prepping an InDesign file to export a “well-formed” file and still end up with a “messy” end result. Instead, Orca’s approach was to ignore InDesign as much as possible, export the bare necessities (styles, ToC, page markers etc.), clean out the junk in the epub it produces using a series of scripted search and replaces, and then rely on post-processing to produce well-formed, accessible epub in a more efficient manner.
To that end we started building two things: a comprehensive standard structure and its accompanying documentation for an Orca ebook, and a series of python scripts to apply that structure to epubs. These scripts needed to be robust enough to work with both new books and to remediate older titles that spanned everything from old epub2’s to mostly-accessible titles that didn’t quite meet Benetech standards.
Python in Epub production
Python was the obvious choice for these tasks. Python is a programming language suited for text and data manipulation that is highly extensible, with thousands of external libraries available, and has a focus on readability. It comes already installed with Mac OSX and is easily added to both Windows and Linux.
Python is easy to learn and fairly easy to use. You can simply write a python script in a text file e.g.:
print('Enter your name:')
name = input()
print('Hello, ' + name)
Then save it as script.py and run it using a python interpreter. As a general rule writing and running python scripts from within an IDE (integrated development environment) like Visual Studio Code, a free IDE created and maintained by Microsoft, makes this pretty simple. Using VS Code allows a developer to easily modify scripts and then run them from within the same application.
Regular Expressions
The other important part of the process and well worth learning as much as they can about — even if they don’t dive into python — is regular expressions (regex). This a system of patterns of that allow you to search and replace highly complex strings.
For instance if you wanted to replace all the <p>’s in a glossary with <li>’s:
<p class="glossary"><b>regular Expression</b>: is a sequence of characters that specifies a match pattern in text.</p>
You could search for:
<p class="glossary">(.*?)</p>
where the bits in parentheses are wildcards…and replace it with:
<li class="glossary">\1</li>.
For each occurrence found, the bit in the parentheses would be stored and then reinserted correctly in the new string.
Once you start to use regexes you’ll quickly get addicted to the power and flexibility and quite a few text editors (even InDesign via grep) support regular expressions.
Scripting Python
With these two tools you can write a fairly basic script that opens a folder (an uncompressed epub) and loops through to find a file named glossary.xhtml and replace the <p class="glossary"> tag and replace it with a <li> — or whatever else you might need. You can add more regexes to change the <title> to <title>Glossary</title>, add in the proper section epub:type’s and roles and more. Since InDesign tends to export fairly regular epub code once you clean out the junk, if you create a standard set of styles, it means you can easily clean and revise the whole file in a few key strokes.
Taking that one step further, if you ensure that the individual files in an epub are named according to their function e.g about-the-author.xhtml, copyright.xhtml, dedication.xhtml etc. you can easily have custom lists of search/replaces that are specific to each file, ensuring things like applying epub:types and aria-roles is done automatically or you could edit or change existing text with new standardized text in things like the .opf file.
If you build basic functions to perform search and replaces, then you can continually update and revise the list of things you want it to fix as you discover both InDesign and your designer’s quirks, things like moving spaces outside of spans or restructuring the headers. If you can conceptualize what you want to do, you can build a regex to do it and just add it to the list.
You can also build multiple scripts for different stages of the process or expand into automating other common tasks. For instance the Orca toolset currently has the following scripts:
- clean_indesign (cleans all the crud out and tidies up some basic structures),
- clean_epub (which replaces all the headers, adds a digital rights file, rewrites the opf file to our standard, standardizes the ToC and landmarks and more…),
- alt-text-extract (extracts image names, alt text and figcaptions to an excel spreadsheet),
- update_alt text (loads an excel spreadsheet that has alt text and, based on image file names, inserts it into the proper
<img alt=""), - run_glossary (which searches the glossary.xhtml and creates links to the glossed words in the text),
- extract_metadata (which loops through all the epubs in a folder and pulls the specified metadata e.g. pub date, modified date, a11y metadata, rights etc.),
- extract_cover _alt (loops through a folder of epubs and extracts the cover alt text into a excel spreadsheet),
- increment_pagenumber (some of our older epubs were made from pdfs that had different page numbering from the printed book, so this script goes through and bumps them by a specified increment)
You can see the InDesign cleaning script here: github.com/b-t-k/epub-python-scripts as a basic example. As we continue to clean up and modify the rest they will slowly be added to the repository.
Documentation
Concurrently to all this Orca maintains and continually revises a set of documents that records all the code and standards we have decided on. It is kept in a series of text files that automatically update a local website and it contains everything from the css solutions we use to specific lists of how ToC’s are presented, our standard schema, how we deal with long descriptions, lists of epub-types and aria roles and a record of pretty much any decision that is made regarding how Orca builds epubs. Because website is searchable, a quick search easily finds the answer to most questions.
Our Books
This type of automation has allowed us to produce accessible non-fiction titles in-house and in a reasonable time framework. Books like Open Science or Get Out and Vote! can be produced in a Benetech certifiable epub in just a few days even though they feature things like indexes, linked glossaries, long descriptions for charts and a lot of alt text that was written after the fact.
Producing an Accessible epub
Orca’s production process has been continually evolving. We started by focussing on making accessible non-fiction epubs without alt text, and then brought alt text into the mix after about 9 months (two seasons)—the scripts meant it was easy to go back and update those titles after alt text was created. Meanwhile we pursued Benetech certification for our fiction titles that were produced out-of-house and developed a QA process to ensure compliance. And just recently we have brought fiction production in-house as well.
At this point, as soon as the files have been sent to the printer, the InDesign files are handed over to produce the epub. Increasingly before this stage, the alt text is produced and entered in a spreadsheet. Then this is merged into the completed epub. A “first draft” is produced and run through Pagina’s EPUBCheck and Ace by DAISY to ensure compliance. Then, along with a fresh export of the alt text in a separate excel file, it is sent over to our production editor who has a checklist of code elements to work through using BBEdit, and then he views the files in Thorium and Apple Books, and occasionally Colibrio’s excellent online Vanilla Reader, checking styles, hierarchy, visual presentation and listening to the alt text.
Changes come back and usually within one or two rounds it is declared finished and passed on to the distribution pipeline. There our Data Specialist does one last check of the metadata ensuring it matches the onix files and reruns EPUBCheck and ACE before sending it out.
Spreading the load
In the background we have marketing and sales staff working on spreadsheets of all our backlist, writing and proofing alt text for the covers and interior illustration of the fiction books so it is ready to go as titles are remediated. The hope is to incorporate this cover alt text into all of our marketing materials and websites as the work is completed.
The editors meanwhile are just starting to incorporate character styles in Word (especially in specifying things like languages and italics vs. emphasis) and working with authors to build in alt text creation alongside the existing caption-writing process.
The designers are slowly incorporating standardized character and paragraph styles into their design files and changing how they structure their documents to facilitate epub exports. They are also working with the illustrators to collect and preserve their illustration notes in order to help capture the intent of illustrations so those notes can be used as a basis for alt text. They are also working to document cover discussion as a way to help facilitate more interesting and accurate cover alt text.
It will take a few more years but eventually the whole process for producing born accessible, reflowable epubs should be fully in place.
The Future
Instagram Since Last Time
Instagram Since Last Time








Instagram Since Last Time










Adventure: Pre days
I haven’t travel blogged in a while so I thought I might give it a go again. We will see if I still want to make the effort each night 🙂
I’m going cruising
Not on my own boat or anything close to it but on a genuine cruise. On this boat. In these cabins (not the balcony ones)…
I had never anticipated going on a cruise. It really is the antithesis of what I look for in a holiday. The only thing L and I have ever considered was a transatlantic cruise on Cunard and that was mostly a romantic tip of the hat to the modernist period.
But I had been thinking it would be fun to spend some time with my mom and frankly I miss the old days of having her to myself when my brothers were of doing stuff. (The benefits of being the youngest 🙂 )
But short term travel is so expensive these days between meals and hotels and it kept adding up. Add to that we’d need some thing to do and I wasn’t sure a walking holiday like Banff or even Calgary was quite the thing. Then it occurred to me there were these short cruises… A little googling found a 3 day repositioning cruise from Vancouver to San Francisco with no stops… and dirt cheap ( ~$500 each with separate cabins and everything included. Perfect!
(I had figured hotels at ~$150/night pp with another ~$100/day pp for nice meals so that added up to closer to $900 pp. No entertainment included so that would add in some extra change as well.)
Booking
So. I called my cousin Anita who has been a travel agent (and owner) forever and whose services I had never availed myself of.
And explained the proposition and left it to her. All in all an enjoyable experience although I will say I ended up being less organized than usually because someone else was taking care of things. Which actually increased the “worry” because you had to trust someone else and ended up double checking everything. I know. I’m weird.
The Cruise
So I fly out in the morning and meet my mom in Calgary and then we fly on to Vancouver. We have half a day to get to the ship (the Crown Princess) so that will be fine. Then it’s 2 full days of floating around until we arrive in San Francisco at 7am on Sunday.
The we catch a flight back and are snug in our own beds on Sunday night ready to start the next work week.
A few costs
So the cruise is cheap. The flights about half again. But man oh man do they ever ding you for insurance if you are older than the average bear. Insurance was almost the same as the flights!
I also added in the “plus” package which took care 0f internet, drinks and gratuities as well as a few other perks. As long as we have 2 drinks a day we will come out ahead. But that was a hefty $250 pp. Still I hope this means other than cabs everything else is paid for in advance and it shouldn’t cost an extra penny.
Hopefully I will post some pictures as we go…
Word from the app
I’m off on a little adventure next week and thought I’d check the status of the WordPress app on my phone to see if blog posts are still easy. Frankly it’s been many years since I’ve used it. Turns out it defaults to the block editor (which I disdain) but I could live with that if it would size images correctly.
Off to do some research… sigh.
I bought this tourtiere at Shoppers Drug Mart last week because A) it’s been years since I’ve had one and B) it’s been decades since I’ve seen the St Hubert logo/brand. Ah, the old days…
An achievement … of sorts
Back in 2014 I started playing Candy Crush. It became a habit. And apparently the other day I hit 4000 levels so they sent me a badge and a congratulatory email.
You are truly among the elite – getting to level 4000 is no easy feat! Well done, and keep up the excellent work!
Beating this many levels puts you firmly in the exclusive top 4% of players! So to celebrate, here’s your Level 4000 Badge – wear it with pride!
Proudly I have never bought anything nor used any of their “community” features. I suppose as habits go, its not the worst one I could have.
Smart lights
…And Home Assistant
So last year I bought a couple of smart lights to play around with. I ended up installing Home Assistant in a docker on my pi (the pi400) to control them.
I have an Office light and TV room light.
- The TV light turns on 1/2 hour before sunset and off at 10:10 pm everyday.
- The Office turns on 1/2 hour before sunset then fades to a calm colour at 7 pm, turning off completely at 10:10pm.
- In the morning the Office light turns on at 7 am and the off 1/2 hour after sunset.
But I want the office light to not turn on/off in the morning when the days are long so I had to write some YAML code which I’ve had to revise several times.
This is a trigger to fire my office light (in the morning) between September 25 and May 15. It still may not be working right, but so far so good.
Edit YAML mode:
condition: template
value_template: >
{% set n = now() %} {{ n.month == 9 and n.day >= 25 or n.month > 9
or n.month == 5 and n.day <= 15 or n.month < 5 }}
https://community.home-assistant.io/t/automation-during-date-range/133814/50
Tickled my fancy
I have a long history with Rocky Racoon… probably one of the few songs I actually know all the words to. And I’ve always had a picture of how it looks in my mind So this just amused me to no end — all it’s missing is the doctor, stinking of gin…
More from Todd Alcott Graphics










