Bison Crossing

A surreal scene of giant bison-shaped clouds crossing the sky over a road, while a woman stands beside a red truck, watching in awe near a “bison crossing” sign

This will probably be the last painting I do for the foreseeable future. It’s been the most difficult picture for me to get through in all my years of painting and illustrating not just because it was technically difficult but because of everything that has happened in my life while working on it. I came close one day not long ago to just deleting it completely because I couldn’t bear working on it or looking at it. I persisted, and I don’t really know why. I’d planned and documented my progress on the painting, my sketches that looked nothing like the final work, my process of getting a new graphics tablet, and I intended to write about all of that. None of that seems to matter now.

I use these complex and detailed paintings as a form of therapy, essentially. I use them to relax late in the evenings usually before bed. Sometimes I’ll work longer on them than I should because of stress or whatever is going on, but it simply doesn’t work anymore. My country is falling apart around me; my neighbors are enthusiastically cheering it on; and when I look at Mastodon or whatever else I am faced with nothing but snide remarks about it and hatred. I lost my job yet again. The company I worked for has gone bankrupt. I am being offered a life raft to the parent company, but it’s really uncertain as to how things will work out. I am thankful for at least that, but because of the way the economy is being manipulated by an orange ulcer the job seems tenuous at best. Lastly, my personal life is in shambles. My girlfriend of many years severed all communication with me quite suddenly and with no warning, and it has left me in a melancholy so severe that I can’t effectively describe it. It also put me understandably in a pensive mood.

I obtained my most recent job the same way I always have gotten a job: because I knew someone on the inside. No one at the company wanted to hire me for the position because of my resumé and likely also because of where I live. That’s always been a problem. There was an internal struggle at the company to hire me, and my eventual boss advocated heavily for me. He had only one team member at the time who built the dashboards in Tableau, and he had to work around the clock to manage everything else. I don’t blame anyone at the company for not wanting to invest in me. I was then working as a graphic designer for $17.50 an hour. Yes, you read that correctly. I was nearly broke. I branched out into doing automation work for the company I was then working for, and that caught his attention. I was hired as a data engineer managing Snowflake, AWS, and eventually also Google Cloud environments because of Google vendor lock-in on Google Analytics 4 providing reporting throughout the company. It was also my job to figure out how to retrieve any data the company needed for internal reporting, and for that I wrote a custom ETL tool in PHP to connect to many API‌s and retrieve data necessary mostly for marketing-related reporting. We also handled automation tasks for many teams throughout the company. Later, we expanded to provide reporting for 6 other sister companies, all maintained by just three people with almost no budget and none of us having a data engineering or computer science degree at all. We were overworked and definitely underpaid for our work. The one who hired me since left the company. There were internal struggles at the parent company to take my Tableau developer colleague and I on as well despite our excellent performance at the job by almost any measure. The people who did endorse us really wanted us, though, and for that I am grateful. But, as I said due to economic factors it doesn’t seem as if my tenure will be long. My current mood notwithstanding, I am still hoping for the best there. You have to or you will go crazy.

I’m 41 years old, nearing 42. I’ve restarted my career multiple times in my adult life. I’ve been a graphic designer, an illustrator, a web designer, a web developer, and lastly now a data engineer. I’ve gotten too close to being bankrupt twice in my life so far. What’s happening right now will likely be the 4th recession in my adult life, and if allowed to continue the way it is going it will likely be the worst. My father was born during the Great Depression, and my mother was born technically afterwards but the war boom never hit where they lived. I grew up listening to horror stories about what they went through to survive. I might have to live through a repeat myself. If my job doesn’t work out I don’t know if I have it in me to try to rebuild my life again. It doesn’t seem worth it. No one has really wanted to hire me for well over a decade anyway. The older I get the more my life experiences make me more cynical about things because I have come to expect the next pitch thrown my way to be a curve ball — the next setback, the next failure.

This isn’t the kind of post that I usually accompany a painting with, but it is forever what I will think about when I do look at it. I know that everyone has their own problems. Many have problems much worse than mine. Nevertheless, all of my problems would be much easier to deal with if she were here.


Boo Boo

A low angle, shallow depth of field shot of a whitetail deer fawn sitting in a thick forest in dappled light

For nearly a year now, painting has been a challenge. Around this time last year, I began working on the piece featured in my previous post. There isn’t any glaring issue preventing me from painting; rather, it’s been a struggle to find the inspiration to pick up the brush. However, I’ve managed to overcome that creative block recently. I opted for a subject that wouldn’t overwhelm me, just to ease back into the rhythm.

Sometimes, the spark for a painting ignites in the most unexpected of places. I stumbled upon an image while mindlessly scrolling through a website — a black cat peering through a gap in some underbrush. It had that unmistakable anime flair, though it was likely crafted by “AI”. But I’m not writing this to dwell on that subject. Surprisingly, it triggered a cascade of ideas in my mind. Initially, I toyed with the notion of painting a fox in a similar setting in my own style, but I’d recently tackled that subject. After much deliberation, I settled on the concept you see above.

The title of this post may raise some eyebrows. For a few years now, Kate and I have been avid viewers of a YouTube channel called The Urban Rescue Ranch. It chronicles the adventures of an eccentric animal rescuer who transformed a property with a troubled history into a haven for various creatures. Lately, he’s been caring for a whitetail deer fawn named Boo Boo. Now, the painting above doesn’t bear any resemblance to Boo Boo, nor was it meant to depict him. Nevertheless, as I showed my progress to Kate she took to calling it Boo Boo as well. Hence, its title is now Boo Boo. Who am I to argue with her?

Color Palette A table of color swatches showing the color palette used for “Boo Boo”
Color palette for Boo Boo

Possibly due to my extensive experience in designing t-shirts, I’ve developed a habit of working out the color palette for my paintings after sketching. Whether I’m working digitally with a plethora of colors at my disposal or painting traditional with a limited selection of tubes, I find it beneficial to establish a cohesive color scheme in advance. This approach simplifies the process of ensuring harmony among the colors, provided I choose them wisely. The color palette displayed above served as my guide, with every hue in the painting derived from it.


On a different note, writing this has reignited my desire to tinker with my website and perhaps delve into writing more. I’m brimming with ideas, spurred on by reading and visiting other blogs recently. I long for the era before social media’s dominance, when self-publishing was the norm. Despite not currently earning a living from the Web due to uncontrollable economic factors, my passion for it remains steadfast. Even if my enthusiasm for maintaining my own website wavers, my interest in the Web itself endures. I’ve grown weary of social media platforms; the only one I frequent regularly is what’s collectively known as the Fediverse, with Mastodon currently being its flagship. While I occasionally post elsewhere, my patience with these platforms is as thin as the hair on the top of my head. Ultimately, my own website remains the one true place I can call my home on the Web. Perhaps, like previous occasions when I’ve expressed similar sentiments, I’ll forget I wrote this and persist in neglecting my personal website, despite my better judgment. I hope not.


IPv6 Struggles

After years of periodic attempts, I finally got IPv6 working on my local network last night. Despite both ISPs I’ve used over the past decade supporting it, none of my networking equipment was compatible. For some time now, I’ve been using custom firewalls, both running OPNsense. Although the software claimed to support IPv6, I couldn’t get it to work despite countless hours spent combing through the forums and subreddit. Recently, I upgraded to a firewall with a few faster ethernet ports, significantly improving file transfer speeds between my computer and my file server. When I migrated I made some improvements I’ve wanted to make to how everything is organized. One item remained. Dammit, I wanted to get IPv6 working.

IPv6 was designed to replace IPv4, promising to solve all its problems and fulfill every network engineer’s wet dream. However, in my opinion, that’s its greatest flaw. Most people who need to use and interact with it aren’t network engineers. I sure as shit am not. I’m just a guy who likes to tinker with electronics, got fed up with subpar overpriced routers, and decided to build his own. Yet, IPv6 is incredibly complicated, completely incompatible with IPv4, and ultimately more trouble than it’s worth for the average end user for his home network. Despite all this and because the router software is theoretically capable of supporting IPv6, it became my goal to make it work.

When I say I wanted to get IPv6 working I don’t mean I wanted to convert my LAN to it. I simply wanted to be connected via IPv6.

OPNsense’s documentation is hot garbage. It’s quite extensive. It contains information on almost everything in the software. So, you’d be willing to bet money it’d be usable.


Gene’s Bayou

A view of a sunset on a Louisiana bayou; an egret is perching on a cypress knee next to a cypress tree looking toward a well-maintained fishing shack that has three pirogues docked at it; a bug zapper is visible hanging by the front door on a porch that is lit by lights strung around the tops of the wooden pillars holding it up

Wow. It’s been just slightly over a year since I last posted anything here. I’ve been really busy but at the same time not really feeling like writing about anything. It’s my fault. There is something I’ve wanted to write about but not wanted to write about at the same time if that makes any sense at all. It probably doesn’t.

Earlier this year I was commissioned by Greg from Gene Cox Grocery to design a logo for a restaurant he was starting and to also paint a large digital painting to put on the wall near the front entrance. I haven’t done a commission in quite some time, and I haven’t really wanted to. But, since it was Greg I agreed. The restaurant was to serve steaks, catfish, and shrimp — typical Louisiana cuisine. I was given little direction as to what to do with the painting other than it should be a bayou scene. Above is what I painted. It is 6 ft. × 3 ft. (1.8288 m. × 0.9144 m.), and is by far the largest thing I’ve ever done. It’s painted digitally to that size at 300 d.p.i. (118.11 d.p.cm). The painting took me about 2.5 months to complete after the initial sketches and color study were approved. I had to send it off to be specialty printed at the quality required, and Greg had to use the carpenter he used for remodeling the restaurant to build the frame for it.

I wanted to get a picture of it, but while it was hanging in the restaurant I was in Canada. Greg received and accepted an offer to purchase his entire restaurant and attached grocery. He immediately took down the painting, not wanting it included in the purchase. I’ll eventually get a picture of its hanging. Sadly I didn’t get to see its hanging in the restaurant itself.


Home

A view of a gigantic turtle with a rocky island on its shell swimming through the ocean; an extremely long school of sardines as far as the eye can see is swimming straight toward the camera; a small settlement can be seen on the island with windmills and terraced farming

It’s been a few months since my last ramble on here. I have a good reason, but I want to write about that in another post a bit later (if I remember). I have this big picture up above to write about right now. It’s a turtle — a really, really big one. Okay; that’s it. Enjoy.


Oh. Still here? Well, I started on this last year in December. I haven’t worked on it all the time since then, just when I had time and felt like it. The inspiration for this was from conversations I’ve had with Kate where she explained myths from her people which depicts the known world of eons ago (North and Central America) as a giant turtle. I started getting images in my head of this world of islands on the backs of giant sea turtles. Seasons would come about due to the migratory patterns of these turtles. The island I ended up depicting was to be windswept due to constant migration by its host. For most of the painting process I had no idea whether I wanted to make the island seem more inhabited or leave it mostly devoid of development. I came to the conclusion it just simply looked better when the viewer had to look carefully for signs of civilization rather than the island’s being one massive city or something of the sort.

The turtle is mostly just a giant hawksbill turtle but with a different, “older” looking face. I chose a hawksbill because they’re really interesting looking and because they’re endangered. When I intially conceived of this idea in my mind the turtle was to be covered in barnacles and stuff hanging off it in a way to depict visually a methuselistic age, but when drawing it the sheer scale of the thing made showing stuff hanging off it to be a tall order as they would be microscopic in size. When I first started painting in detail on the creature, the texture I painted in to represent barnacles and such ended up just making the turtle look filthy. That would in turn make it appear monstrous. It’s not a monster but an animal, likely magical because nothing that size could exist. Seriously, look at the shape immediately under its right shoulder; that’s a blue whale, the largest creature ever known to have existed — bigger than any dinosaur we’ve ever dug up. I, in the end, added a few barnacle-looking things on its body thinking if there’s mountainous turtles there’d be giant barnacles, too. I still dispensed with the texture, though. On the bottom there is a miles/kilometers/whatever long school of sardines. This was the most difficult thing I’ve drawn in living memory. It took forever to figure out how to get the scale right on them and to draw the ones closest to the camera; they’re the most detailed.

I struggled with the title since I first started on it. I never could figure anything out that fit, and truth be told I’m not entirely sure about the title still. I’m going to run with it anyway. I felt like it should be something simple, even one word. What I have chosen works even if I’m incapable of thinking of a better title. For the imaginary people who live on the turtle island it would be their home.


Photoshop Clear Mode Toggling

Usually when listing grievances concerning Photoshop or any Adobe product the typical complaint is about the subscription model. Believe me, I’m not a fan. This post isn’t about that; but first I do want to air some grievances.

I have a soft spot for Adobe Photoshop because it is how I truly began digital painting. Photoshop is a venerable program, having been released to the public since 1990. I’ve used it since 2.0 in 1991 on the Macintosh II. I was just a kid. There were no layers, only one undo, and no custom brushes; but it was magic. I would spend hours upon hours drawing random things in it with a mouse and later scanning my drawings in to manipulate them. I would use it for what it was designed for — to manipulate photographs — but the truth is that what I wanted to do was draw on a computer, and that wasn’t feasible for at least half a decade or more from then when I bought the first model Wacom Intuos tablet. I could finally draw on my computer.

Back in the day we used Photoshop because we had to. It was the only name in town for that sort of thing that was worth using. Painter is an application that is nearly as old as Photoshop is which is designed to more accurately mimic natural media and is geared more toward digital painting. Unfortunately, it is janky and incredibly slow; in fact it always has been despite decades of development and changing hands between companies. Deluxe Paint predated Photoshop which is something Amiga fans love to point out, but it was a bitmap pixel editor meant largely for low color 8-bit 2D 1980’s video game graphics; it was even developed by Electronic Arts. This is not a knock at pixel artists, but I’m talking about painting here. All of the other alternatives back then are not worth mentioning. Today, there are numerous good alternatives for painting. Adobe even has another application which is purely meant for digital painting, but it’s only available on iOS and also Windows — if the Windows computer has a built-in pen display. Professionals who have paid upwards of $3000 for Cintiq pen displays are shit out of luck.

Photoshop has always been marketed and treated by Adobe mostly for photo manipulation. Digital painting, despite being important for two of the biggest entertainment industries in the world, has largely been treated as the equivalent of a red-headed stepchild. Bones were thrown at digital artists as far back as Photoshop 6 when what we think of the Photoshop brush engine today had its beginnings. Since then we’ve gotten arbitrary canvas rotation in CS4, the nearly useless mixer brush in CS5, finally a color wheel in Photoshop CC 2018, and sometime since then a clear blending mode for brushes.

Why Use Photoshop, Then?

A lot of the applications linked to above have surpassed Photoshop when it comes to digital painting, but I personally often find myself gravitating towards Photoshop because of its familiarity but also because manipulation tools are just as important when digitally painting as it is when manupulating photographs; they are either awkward to use, slow, or nonexistent in applications meant for digital painting. Also, if I’m starting something and Photoshop is already open I will often just use Photoshop; sometimes it truly is a whimsical choice. Out of the listed applications above I use Krita the most of all because its brush engine is more customizable than anything else I’ve seen. It is fast when painting even with large canvas sizes, but adjustments like levels, curves, and gradient maps need a lot of work. Krita contains a lot of quality of life improvements when it comes to user experience that I miss when using Photoshop. Krita doesn’t have a separate tool for erasing. You use a brush and set eraser mode when needing to erase; it’s an eraser button on the top horizontal bar. There is also an erase blending mode. To make things extra useful eraser mode can be toggled by simply pressing b. Recently in Photoshop a clear blending mode was added to do exactly this, but Adobe didn’t deign it worthwhile to assign a shortcut for it or to even make it possible to do so. Deep in Adobe Photoshop CC 2020’s release notes it states that ~ should toggle between brush and eraser mode using the same brush, but as far as I can tell that has never worked. I wanted a way to toggle this. I figured something out and thought I should share it.

AppleScript to the Rescue

AppleScript is a macOS feature that has existed as far back as I can remember, and it (sadly as will be seen in a bit) is probably my first introduction to programming, writing scripts to prank my dad on the aforementioned Macintosh II using a book a friend of his let us have for reference. I should mention that this trick is Mac-only, and I haven’t a clue what the equivalent on Windows is — or if there even is one.

To toggle between blending modes one must click on the dropdown on the top horizontal bar and manually select the blending mode. Nobody ain’t got no time for that. AppleScript has accessibility features that allow it to click buttons and select things in an application’s UI and after testing that Photoshop was somewhat exposed to this API I was able to come up with a script to toggle it for me:

tell application "System Events" to tell process "Adobe Photoshop 2022"
	tell application "Adobe Photoshop 2022" to set _currentTool to current tool

	if _currentTool is equal to "paintbrushTool" then
		set _focusedWindow to null
		repeat with i in windows
			if focused of i is true then
				set _focusedWindow to i
				exit repeat
			end if
		end repeat

		if description of _focusedWindow is equal to "standard window" then
			set theWindow to null
			repeat with i in windows
				-- Photoshop doesn't expose anything good to identify the window.
				-- Its position will always be at the top, so let's use that...
				if position of i is equal to {0, 24} then
					set theWindow to i
					exit repeat
				end if
			end repeat

			if theWindow is not null then
				set brushMode to pop up button 1 of theWindow
				set currentMode to value of brushMode

				set newMode to "Clear"
				if currentMode is equal to "Clear" then
					set newMode to "Normal"
				end if

				click brushMode
				click menu item newMode of menu 1 of brushMode
			end if
		end if
	end if
end tell

That’s great, but there’s nothing in there about assigning the script to a keyboard shortcut.

Enter skhd

skhd is a third-party daemon that runs in the background that intercepts keypresses and performs shell commands. macOS has a built-in global shortcut feature that’s in the Keyboard system preferences pane, but it’s quite limited in the commands it can assign and what can be assigned. Skhd is designed for people who want to transform macOS into window managers like i3 using things like yabai. Yabai is in fact developed by the same developer as skhd, but I use it without yabai despite its original intent. My keyboard doesn’t have an eject key like typical macOS keyboards do so the control + shift + for turning the screen off doesn’t work. With skhd I can assign control + shift + esc to pmset displaysleepnow, allowing the feature to be used on my escape key less keyboard. One can execute AppleScript through the shell, so skhd can be used in much the same way.

Skhd can be installed and started through Homebrew:

brew install koekeishiya/formulae/skhd
brew services start skhd

Configuration is easy, being a single file located at ~/.skhdrc. Documentation may be found on skhd’s GitHub page as to everything that can be done. I’ll instead focus just on what is necessary to execute the AppleScript above. Here is an excerpt of my configuration:

ctrl - e [
    "Adobe Photoshop 2022" : osascript ~/Scripts/Photoshop/"Toggle Clear Brush Mode".scpt
]

This snippet above tells skhd to bind control + e to osascript ~/Scripts/Photoshop/"Toggle Clear Brush Mode".scpt but only when Adobe Photoshop 2022 is the active application. This assumes the script is stored in ~/Scripts/Photoshop/Toggle Clear Brush Mode.scpt, so if wanting to store it somewhere else make sure the path is changed in ~/.skhdrc.

If everything goes okay pressing control + e in Photoshop should cause the dropdown to toggle between Clear and Normal blending modes.

Security

macOS has a lot of security features to keep arbitrary code from being executed without the user’s permission. Sometimes macOS’ security features while well-intentioned feel to be less thought out and especially far more annoying than they should be, and this is certainly one of those situations. When running skhd for the first time when starting it with Homebrew above it should cause a dialog box to appear asking for permission to access accessibility features; grant it permission. If one doesn’t grant it permission that dialog box won’t appear again, and anything skhd does will fail silently. It’s poorly designed as the user should never be able to put themselves in a situation where something they believe should work won’t without no obvious way to rectify it. This is a normal occurrence in Windows but hasn’t been in macOS. In case the dialog was accidentally dismissed, permission may be granted again by going to AppleSystem Preferences…Security & PrivacyPrivacyAccessibility. Clicking the + button will allow for selecting the executable to grant permission. If installed through Homebrew skhd will be located at /usr/local/bin/skhd.


HTML-Parser & HTML-DOM

I mentioned in Where Have the Years Gone? that Jeff and I have been working on a PHP HTML parser and an HTML DOM implementation and that I would like to write about it more; this is my attempt to do so. The impetus for these libraries was needing a better scraper for our RSS aggregator server, The Arsse. I had written an HTML5 parser back when the parser specification was new, and up until last week this website was generated using it. It was sloppy, in a single 20,000 line file, only supported UTF-8, and wasn’t updated for all the changes in the specification from when I first wrote it; it was simply not suitable for use in The Arsse.

The Arsse uses PicoFeed to parse feeds and scrape websites. PicoFeed was originally authored for use with Miniflux, and the library was abandoned when the developer decided to switch to Go from PHP — leaving us in a pickle. Thankfully, someone picked up the torch, and we’ve contributed to the project since then. However, we’d still prefer to write our own because of issues we’ve found along the way; we would also like to support JSON Feed, too, even though we have not entirely glowing opinions of the format ourselves. It borrows far too much from RSS and not enough from improvements brought forth by Atom — repeating 15+ year old mistakes in the process.

HTML-Parser

I began writing the new parser in 2017 based off of the WHATWG living standard instead of HTML5 while Jeff was still focused on The Arsse proper. I, unfortunately, became bored with it and moved onto something else; the process is mostly tedium. He decided it was time to work on it after beginning Lax, our in-progress feed parser mentioned above. His working on it got me interested in it again, and over time he became focused on the parser itself while I focused on the DOM. There were also a couple of branching projects that resulted from this, namely a set of internationalization tools that actually conform to WHATWG’s encoding standard (PHP’s intl and mbstring extensions don’t handle this correctly) and a mime sniffer library. Jeff wrote the entirety of these with my providing nothing but occasional input.

There are other PHP HTML parsers, most notably the widely used Masterminds HTML5 parser. Masterminds HTML5 parser isn’t very accurate and in some cases fails to parse perfectly valid documents at all. HTML-Parser conforms to the specification where it can. It is also extensively unit tested, including with html5lib’s own tests. Because of this it is also slower than Masterminds’ library. We believe this accuracy is more important — especially when we attempt to scrape websites that may or may not be well-formed at all. We need the result to be what a browser would parse.

Originally, the parser and an extension to PHP’s dom extension were included together, mostly existing to circumvent PHP DOM bugs when appending and when handling namespaced attributes. This, however, caused parsing to slow down a bit, and the more I added to the DOM to fill out missing features the slower it became. The decision was made to separate the two and bake the circumventions necessary for accurate parsing into the parser itself. This was a blessing in disguise which will become apparent later.

After an initial write and working out bugs when unit testing against html5lib’s tests we went through a period shaving off fractions of a second here and there optimizing it when parsing an extremely large document: WHATWG’s single page HTML specification. I think initially it was around 30 seconds on my computer. Today, it’s around 5.5 seconds. The official benchmarks listed in the README of HTML-Parser are from Jeff’s computer, one slightly slower than my own. We still have some more ideas for improvements which might shave a bit more off the top. However, we don’t want to sacrifice readability of the code; the code still needs to be maintained by humans. Well, Jeff might actually be a robot…

Initially, a conforming HTML serializer was part of the DOM part of the HTML-Parser library. I had written a fully functioning and unit tested serializer. After the two parts were separated into separate libraries, Jeff decided it should be part of the parser and wrote another one. I just finished writing my initial stab at a pretty printer for the serializer in HTML-DOM, so I migrated everything over to Jeff’s serializer when I was able to. HTML-DOM still serializes as it should, but it’s largely from HTML-Parser.

HTML-DOM

When initially writing the DOM classes they were simple extensions of PHP’s DOM using its DOMDocument::registerNodeClass method. As I dug deeper into the WHATWG DOM specification, I discovered that it was too difficult to follow the specification as I was running up against type errors in PHP’s XML-based DOM. The straw that broke the camel’s back was when the node passed to Document::adoptNode could not be passed by reference. Since the library wasn’t married to HTML-Parser anymore I was free to do whatever I needed without worry about how much it would affect parsing speed. My decision was to then wrap PHP DOM’s classes. I could then do whatever I wanted and let PHP’s DOM handle it internally. This benefitted me greatly as soon as I started running unit tests.

PHP’s DOM is at best a flimsy and buggy wrapper written to access a buggy and antiquated XML library that conforms to no specification whatsoever, new or old. It returns empty strings when it should return null in some circumstances. It has issues with namespaces, especially concerning the xmlns attribute. When inserting nodes any non-default (in PHP DOM’s case null is default) namespaced elements that are children of non-namespaced elements are prefixed with default. Same goes for attributes. Also due to what presumably is a memory management bug in the original xmllib the more namespaced elements there are DOM operations become exponentially slower. This leads us to use null internally while exposing the HTML namespace externally. In reality, there needs to be a new DOM extension for PHP, but that is beyond what I am capable of programming. Wrapping the classes allows these bugs to be circumvented at least.

It also allows templates to be implemented as specified. While templates work as specified in HTML-DOM, they were a colossal pain to implement because of the XML-based inner DOM. A lot of code is written in both HTML-DOM and HTML-Parser just for handling templates whether it is for parsing, insertion, and especially for serializing. In my personal opinion template elements are the most ill conceived thing in HTML at present. They were designed to be used within a modular loading system. One such system was specified and implemented in Blink, but some drama that I don’t quite remember the details of ensued; it never was implemented in anything else and was subsequently removed from Chrome. JavaScript modules are now supported in place of them. Template elements are treated differently when parsing and have different rules when manipulated with the DOM, and is an everpresent exception throughout the specification. Storing HTML and CSS in JavaScript is a constant source of consternation from old hats like me who during the web standards push in the late 1990’s and early aughts had separation drilled into us, but as soon as HTML imports were abandoned there has simply been no other alternative. It’s bonkers to have JavaScript append template elements to the document when the HTML and CSS for components can simply be stored in template strings in code. Having them already in the document is inefficient as well because they’re downloaded and therefore cached for every page; in JavaScript they’re downloaded once and cached once.

While developing this library I discovered another attempt to do something similar: PhpGt. Somewhere along the path of their development they came to the same conclusion that the built-in classes must be wrapped to get anything meaningful done. That’s where the similarities between the libraries end, though. It oddly wraps all PHP DOM classes such as DOMDocument, DOMElement, DOMText, etc. when only DOMDocument is necessary; handles templates incorrectly; has multitudes of factory classes that overcomplicates things further; and it also seems to follow Mozilla’s MDN documentation instead of the actual specification. This has led to widespread bugs and implementation errors because MDN is a JavaScript developer’s documentation, not an implementor’s documentation. Other differences are that PhpGt’s DOM implements individual element classes for everything while ours only presently supports what is barely necessary for the element creation algorithm. There are plans to support more in the future as time permits. Our library is also backed by a conforming parser while PhpGt’s isn’t. A full list of what HTML-DOM supports is available in its README along with any implementation details and deviations.


Both libraries outlined above are available on Packagist as mensbeam/html-parser and mensbeam/html-dom and may be installed through Composer.


Fox

Digital painting of a fox resting on a tree root

Last May I was playing around with Krita’s new RGBA brushes. It’s difficult to explain what they are, and RGBA isn’t descriptive as to what they are. In most graphics applications a mask is provided for a stamp used as the brush. This feature in Krita allows you to provide a color image, and it — color and all — would be used for the stamp. One side effect of this is that a grayscale image with bump textures can be used, creating the illusion of varied paint thickness on a brush by using the L*a*b* lightness channel as data for the brush’s stamp. If applied heavily the look of impasto can be achieved. Krita’s expansive brush settings can be used to control this by various ways. I don’t know whether I described this well or not. Krita has a demonstration video showing the wet variety of RGBA brushes that didn’t exist yet when I painted this, but it’s the same premise; view that if you’re interested in learning more.

Like with Keeping Watch this one began as a doodle as well, and with Kate’s encouragement it turned into a full painting where I experimented with brushes I created using the methods described above. I love experimenting with color, so I fired up Coolors, and pressed the generate button a few times until a palette popped up that was to my liking. I tweaked the colors here and there to make it harmonious with what I wanted to paint, but if my memory serves me it wasn’t anything drastic.

Color Palette A table of color swatches showing the color palette used for “Fox”
Color palette for “Fox”

This is a practice painting, and it is referenced heavily from a photograph I found on Unsplash that for some reason I can’t seem to find no matter how I search for the subject matter. Composition was a bit different, and the fox was resting on rocks instead. The original image is 9921 × 7016 and would be about 84 cm. × 60 cm. when printed as intended.


Where Have the Years Gone?

What? After a year and a half of nothing but crickets from this website I am finally writing something? Yeah. It won’t be much, but I should start fresh somewhere at least. These past couple of years have been unpleasant, right? The world appears to be coming apart at the seams. Far too many people have quite literally lost their fucking minds, and I just didn’t feel as if anything I did or wrote here was that important. That, of course, yet again reneges on a desire I had with this weblog where I would try to reclaim a wee bit of the Web back for myself.

It seems to be a time of reneging for me. I’ve returned to macOS after stating that I would be moving over to Linux, and even before that I returned to Twitter after stating I wouldn’t be using it anymore. I have my reasons for both, but they are indeed uncharacteristic of me where I usually make a decision and stick with it. I moved back to macOS because being able to easily use applications necessary for my work and most importantly full color management outweighs any other benefits. It helped, too, that my issues around Clover became nonexistent when OpenCore came on the scene. It’s easier to use and more stable. I don’t know what I will do in the future when Intel support is dropped from macOS, but I will cross that bridge when I get there. I still do have Linux installed, and I do continue to use it — no, really.

Moving back to Twitter is a bit different. I never stopped checking it, but I was completely silent on there for quite some time. This led to a few people who don’t read my blog to wonder where I’d gone to. I’d like to thank them for checking in on me even though I was alright. It’s still the hellsite it was when I wrote that blog post a few years back, and of course it’s only gotten worse because apparently just trying to remain alive is political now. At some point — I forget precisely when — I unfollowed almost all political stuff on there, uninstalled all of the apps, and started conversing with some people again. I now check it almost exclusively on my computer where I can use custom scripts and stylesheets to remove crap from the webpage. I don’t use it like I used to, and I probably look at it once a day if that. I mostly keep it around to check in on people I know, view pretty art, and occasionally — that adverb doesn’t reflect the gigantic tumbleweeds rolling by — posting my own artwork.

My work is probably where I have suffered the most these past couple of years. While in the past I have used painting as a sort of therapy, recently I’ve been incapable of doing even that, and depression is the only thing that exists in the vacuum formed from that absence. The past several years have been a series of disappointments to me, disappointment in myself, and it’s been difficult to cope — especially since the advent of COVID-19. It doesn’t mean I’ve produced absolutely nothing. I’ve made a few things, but every time I have it just feels futile; few people seem to care. I am not saying this trying to frame my self-worth by my productivity or even by the popularity of my artwork (or in my case the lack thereof). That’s an entirely capitalistic thought process that — truth be told — only leads to self-destruction as an artist. No, it’s just that with every passing year I feel the clock ticking more easily than I could the year before, and that mindset is where the title of this post comes from. I have so far been focusing on my artwork, but my actual work plays a larger role. I don’t have health insurance, and I can’t afford it because paying for a policy would mean not eating or not paying for the house I live in. I make barely enough to pay my bills, and it’s always on my mind. I do consider myself lucky because I know plenty of people who can’t even accomplish that. Indeed, I am better off than I was five years ago when I was within a month of not being able to pay my mortgage. Yes, I have a mortgage thanks to prior employment; having that is something many don’t and won’t ever have these days. My work environment is pleasant most of the time, and I get along with everyone there. However, being genuinely thankful for the crumbs I’m given while being surrounded by Everests of cake isn’t gratifying. Every attempt thus far to improve this situation has been met with failure. No one — and I mean no one paying a living wage — wants to hire me. That alone is an ever increasing source of my depression.

Everything isn’t bleak, and I truly didn’t mean this post to be a huge downer. I wasn’t even sure I was going to include anything about my mental state because of my aversion to posting personal stuff online. Hey, I’m just being honest. Thanks to COVID everyone seems to have issues to work out, so I might as well hang my own laundry out to dry. It’s especially difficult for men in the world the way it is to express insecurities without receiving ridicule in return. I personally have in the past experienced that ridicule. Thankfully, I do have support from my girlfriend, and I am truly blessed to have her in my life. And, yes, I tell her this regularly. How she puts up with me I do not know. Just her presence alone has allowed me to continue on.

I have not been idle. I have worked on a few relevant things outside of work. Nearly a decade ago some time after the specification was released for the HTML5 parser I decided I would like to write an implementation of it in PHP because PHP’s DOM extension and parser were made for XML and couldn’t really parse modern HTML. I was successful. The library was a wreck, but it worked. I ironed out bugs as I encountered them, and up until just a few days ago this website was built using that parser as part of a static site generator. A lot has changed since then; template elements didn’t exist then just to give one example. I started on another one a few years back, but I became bored with it — squirrelling over to some other project whatever that was. Jeff then became interested in a parser for a scraper he was working on as part of our open source RSS aggregator, The Arsse. This got me interested in it again. After my initial work he focused on the parser side of things while I worked on the DOM. Two projects are the result of this endeavor, HTML-Parser and HTML-DOM. HTML-Parser allows for per-specification parsing of HTML documents, and HTML-DOM allows for per-specification DOM manipulation by wrapping PHP’s extremely buggy DOM extension and working around its innumerable bugs. Both are used in this website’s static site generator. In addition, I’ve written a syntax highlighter in PHP called Lit which does TextMate-style syntax highlighting. I hope to write more about each of these in the future. Oh, and Lit is also dogfooded by being used to highlight code in posts on this website.

This website also changed a bit, but it’s not a redesign. This was more of a retooling — an attempt to also use what I’ve been working on. The most notable change is the switch in the page’s footer which allows for switching between a light and dark theme. The last iteration of this website switched themes based upon one’s preferences, but this one also allows for dynamic changes as well. Unlike similar switches on many websites, mine is also keyboard accessible. Almost everything else is identical or nearly so.

Sorry if I rambled a bit in this post, but I tried to keep it as organized as possible considering this has been more of a mind dump than anything. I have written a lot of code in my absence. I do have some ideas for my artwork moving forward, but I will save that for another post. I think I’ve written enough for today.


The Three Bandits

Digital painting of three raccoons raiding a vending machine

This year has been quite the anxiety-inducing one, and the best way I know of for me to relax is to paint. I’ve always relaxed by drawing or painting for as long as I could rememeber. As a child my parents would just hand me a notebook and a pencil to keep out of their hair, and my family would gift me three subject notebooks for my birthday and Christmas. Truth be told they were as much a gift for my mother as they were for me. Today, I just paint or draw before bed to relax and empty my brain before sleep. I’ll work on the same image for months. I started on the one above in late April.

I had been struggling for a while coming up with an idea for a painting I could do, and I was just looking through random images. I ran across a photo of a gas station that was lit from above by a sodium vapor lamp with the scenery outside of the lit area being blue. I knew I wanted to do something with that kind of lighting. It just took much longer to figure out what the subject matter was going to be. I just came up with this idea of raccoons raiding a vending machine randomly.

I think I had the most fun on this painting working out the lighting, so much I introduced more light than would normally emanate from a vending machine, including the area at the bottom where the one raccoon is digging inside the machine for goodies. It sort of glows like the briefcase in Pulp Fiction. Another fun part was painting the labels on the snacks in the machine. They’re all mostly vaguely like real world products but yet not. Some are a bit vulgar, too. Of course!

The original of this image is 6136 × 8496 and would be about 24 cm. × 34 cm. when printed as intended.