Looking for writing-related posts? Check out my new writing blog, www.larrykollar.com!

Monday, November 23, 2020 No comments

Catching up, Nov 2020 edition

I had a few posts written up for our brush with Zeta, and never published them. I back-dated them to the dates they should have appeared, so (unless you're reading this late Monday night) scroll down to see all the… um, fun.

More coming tomorrow, if I don’t get totally distracted (again).

Saturday, October 31, 2020 3 comments

Zapped by Zeta, day 3: Live-action Creepshow!

I felt pretty decent in the morning, despite all the drama. Still, the house was dark and still (no electricity). Fortunately, by the time I was ready to get moving, Wife and Daughter Dearest had come back from a Dunkin' (and gasoline) run and brought me a large coffee. So… caffeinated and needing some Internet, I rolled outside to tackle the generator.

After the “fun” yesterday, the gennie was still sitting in the box, right behind the blood-spattered tailgate of M.O. the B.B. Armed with a utility knife and a garage full of tools, I began the assembly. Despite my missing the installation instructions (and cursing the people who didn’t put them up front where they couldn’t be missed), I got it put together, oiled, and gassed up.

The brand-new engine didn't want to fire up (thankfully, it’s an electric-start), so I got the starter fluid and gave it a squirt. After a few tries, in which I considered the possibility we had a dud, it fired up and ran. Woohoo! I plugged it in, threw the transfer switch… and it died.

Okay, I had already flipped off the high-draw stuff at the breaker box (oven/stove, A/C, water pump, water heater), so I turned off everything and restarted. I turned on one room at a time… and somewhere along the line, it died again. At this point, I was certain I had a dud, but it did run some stuff. I figured if I could get the lights and at least one fridge going, I could live with this for now. After a few fits and starts, I got the kitchen fridges up, and then the freezer in the garage. At this point, we were due to get to the church for our Trunk or Treat thing, so I left the gennie running and hoped for the best.

My original Halloween costume plan was to be the Grim Reaper, complete with a real scythe. Hanging from the blade, a sign: Wear a mask! I have enough work already! But given all the “fun” I had yesterday evening, I just ran my booth. I had a BB gun and targets, with candy for anyone who could hit a target (and consolation candy for those who couldn't). Amazingly, the first person to hit the smallest target was a kid in an inflated (with battery-operated fan) dinosaur costume!

As for me, I wore a hat to keep the adults from losing their latest meal over the bloody mess that was still my scalp. But for the older kids, I offered: “You want to see a live-action creepshow?” They all said yes, so I would remove my hat and bow. Daughter Dearest would get the Shivering Collywobbles every time she made herself look at the staples, and Mason grimaced when he asked to check as well.

Hey! You want to see it, too? Okay! After all, it’s just a flesh wound.

Hurts to see it? Think about how I felt!

The staples come out in a week. Washing my hair is going to be… interesting… until then.

Finally, we went home. The gennie had run through its gas allotment, so I refilled it. This time, it started without a hiccup, and sounded a lot better than before. Maybe it just need a few hours of break-in time? It gave no grief over us flipping on the lights, fridges, and furnace… so the wife decided to extend the test. Our old gennie wasn’t quite up to running the water pump, but the new one was rated for 150% the old one’s capacity. We turned on that breaker, and the gennie surged but handled the load. Running water, yay!

The final test: the water heater. I got the wife to wait about 15 minutes, to give the water pump time to finish pressurizing the system, then we flipped that breaker. A brief surge, but it held! We prioritized the showers, but nobody got ice-cubed. We turned on everything but the A/C and stovetop, and mirable dictu, the DSL was waiting for us, wondering where we had been.

Now that we have all the comforts of the grid, I expect the “real” power to come back on pretty quick. Fortunately, there’s a website that will tell us when that happens.


Friday, October 30, 2020 No comments

Zapped by Zeta, day 2: It's Just a Flesh Wound

Still no power this morning. We decided to hit the retail district to:

  1. Get breakfast
  2. Look for a generator
  3. Pick up some other odds and ends

As expected, Home Despot and other big-box stores had sold out of generators. Other things we needed, we were able to find. Then the wife, on a whim, called a plumbing and electrical supply joint where she gets farm stuff.

“We don’t have any now,” they told her, “but we’re expecting a shipment around 2 and we’re open until 5.” She gave them a credit card number, and they virtually set one aside for her and promised to call when the truck came in.

Then, she and Daughter Dearest had a meeting at church to do some last-minute planning for the Trunk or Treat event we’re doing tomorrow afternoon. I hung out outside with the kids (including AJ, who was happy to be in the stroller as long as the sun wasn’t in her face). I took AJ inside after a while, figuring she would be ready to eat. She munched happily away at her veggie puffs, then gobbled a container of Apple Chicken mush.

The wimmin-folk got back as AJ decided she was done eating, and wanted to sit in my lap as I had my sandwich. Time was getting tight, especially since this guy who helps with farm repairs and upgrades had all but moved into M.O. the B.B. We hurriedly cleaned it out so everyone could pile in (and have room for the gennie in the back), and got on the road, arriving just in time.

Seized by some impulse, the wife bought a second gennie for Daughter Dearest, and two guys hoisted the boxes off the dock and into the voluminous back-end of M.O. the B.B. We headed home at a much more sedate pace.

But the lights aren’t on, and mine nearly got put out. I wrestled a box into a dolly, hoping I could slide it down the tailgate and onto the ground. Gravity had its own ideas though, and I got jerked out of the bed and flung headlong into the dolly. At first, I thought I’d just banged my head a good one, and I could finish the job… then blood started pattering out of my hair. Mason seemed calm, although he was near panic, and I pressed down on the laceration.

“It’s only a flesh wound,” I said. Too bad I didn't have the chance to yell, “Hey, y'all watch this!” Anyway, pressure did what was needed, and the wife and Mason hustled inside to get a cloth and some ice to help with it. Daughter Dearest came up and got the kids, and wife took me to the urgent care, getting there 10 minutes before closing.

“Uh,” said the doc, when he saw the gash, “that’s bigger than what we’re equipped to deal with. You need to go to the ER.” That was another 15 minutes down the freeway, but pressure and ice had done for the worst of it. I continued pressure, switching hands when the active one called for a shift change. This may have been a tactical error—since I wasn’t bleeding all over the place when I arrived, I was in the normal queue. The initial intake generated an amusing side-story: the blood pressure cuff got so tight, my hand went numb, then the nurses put the oxygen sensor on that hand. “No way he’s an 83,” one said.

“Try the other hand,” I suggested. “That one went numb.” They did, and were much more satisfied with the results. After that, a P.A. cleaned around the worksite, put staples in my head, and sent me home. There, wife and I got most of the rest of the bloody mess cleaned off.

So tomorrow, I will get the generator going… if the power doesn’t come back on first.

Thursday, October 29, 2020 No comments

Zapped by Zeta, part 1: Tropical Snow Days

This one didn’t seem as scary as Opal in 1994. Just like Opal, Zeta passed by overnight (or very early Thursday morning). The heavy rain came in ahead of the heavy wind, and some of the gusts got pretty loud. The power crapped out at some point, which we had expected. The school system decided to close ahead of the situation, so Mason got a tropical snow day.

But when we all dragged ourselves out of bed, we all soon dragged out the chainsaws to clear the roads enough to get somewhere. There were trees down everywhere. We had recently taken down a bunch of trees near the manor, so maybe that helped us dodge a bullet. So… open the garage and drag out the generator.

It started, but the lights didn’t come on when I threw the transfer switch and plugged in the house. I have two cords, so I tried the second one. No dice. I plugged a fan into one of the outlets. Nothing. Seeing as people have probably made a run on any place that stocks generators, that leaves us at the mercy of the power company. With 8,000 houses in the dark, there are likely 7,999 ahead of us.

So… I plugged my phone into the work laptop to help charge it, and used my hotspot to get to work. That lasted through the morning. The laptop battery hadn’t quite wheezed, but I need a few minutes to let co-workers know I’ll be out of pocket if the power isn’t back on in the morning. If not for the pandemic, I’d hole up in a coffee shop in the retail district (of course they have power), but given the third surge that’s not what I’d call a smart maneuver. To at least keep the phones charged, I pulled the battery out of the Miata and connected it to a solar panel. It sits outside during the day, soaking up lots of sun (and charging the tablet), and then comes in for the night to deal with the phones.

I often had to remind myself it isn’t Saturday, and that I don’t have to worry about church in the morning. We heated leftovers on the grill’s side burner for supper, then Mason and I took a bike ride. The school robo-called us to tell us no school on Friday as well, so that’s our second tropical snow day.

Tomorrow, I’ll probably spend much of the day cutting firewood. Between one thing and other, we never got around to doing that. But now there are downed trees to clear. Maybe I’ll get another bike ride in with Mason. He’s wanting to get to where we can ride to town (10 miles each way) for (root) beer and tacos. We’re building up to it.

Friday, October 23, 2020 2 comments

Shakedown cruise

When I last mentioned it, the county was stripping the pavement off our road in sections, and widening the roadbed. Now, they’ve finished repaving and striping. The “bike lanes” are maybe 18" (about 50cm) on either side… I would have been fine with them putting both shoulder strips on one side. But whatever… it’s a lot safer to bicycle now, both for us and people who come up from the metro to ride.

I wanted to take the Fuji out for a shakedown cruise, but Mason threw in a wrinkle: he wanted to join me. We took a short trip down to a nearby church and back, and found his mountain bike wasn’t really suited for road riding. “I guess I need a road bike,” he said, and I suddenly remembered.

I don’t know where it came from, or how long it’s been sitting there in the back of the detached garage, but I had a small-frame road bike—to be precise, a Schwinn Prelude. Solar suggests it’s about mid-80s vintage, and a “pretty decent bike for its day.” It’s a 12-speed, and the shifting is like-new smooth. The tubes needed replacing—one had a stem separation, the other missing completely—but I happened to have two tubes on hand. The tires themselves have also seen better days, but are still round and not coming apart. I figured they would be good for a few miles, anyway. That, and a little chain lube, and it was ready to adjust. First adjustment: remove the foot straps. He’ll want them later, but for now, one step at a time.

The frame, although small, is a couple inches too big for Mason. I vaguely remember offering to get it rideable for Daughter Dearest, back when she was a teen, but she demurred. And yet, with the seat all the way down, it’s a perfect pedaling height for Mason. He provided a little entertainment, getting on it the first time, but soon took it a couple laps around the slab between the garages. By then, it was getting dark, so we hung it up for the night.

This afternoon was perfect for being outside—upper 70s (F), partly sunny, and just a little breeze. I aired up the tires on the Fuji (the Prelude was still holding its air, which is good), we strapped on helmets, and Mason took a couple laps around the driveway. He got more confident about being perched 'way up there, and off we went.

Sector 706 is pretty hilly, and Mason was soon waxing enthusiastic about how much easier it is to pedal a road bike uphill. We rode a mile or so, then reached a long uphill climb, and we got about 3/4 of the way up before Mason decided it was time to turn around. The Fuji mostly performed well, but I found that pesky front derailleur wasn’t quite as dialed-in as I had thought. Mason didn’t notice anything on the Prelude that needed adjustment, so I put Fooj back on the stand and tightened the cable until the front derailleur did what it’s supposed to. So now it’s dialed-in… at least until the cable stretches again.

If we can get out a couple days each week, we’ll both soon be ready to tackle those hills. Mason’s already talking about riding to town (10 miles each way) or all the way to the retail district (another 5). We’ll need to be in much better shape for that, though. He also needs to feel confident enough to reach down and work the shifters. Despite their analog look, they are indexed.

He’ll probably be tall enough by spring to fit the frame, and maybe get a couple years out of it before he outgrows it. So I took tomorrow off, because Mason has a day off school as well. We’re going to ride a little more, then hop over to the local bike shop and get him some new tires. I might get a new bike carrier, too. The one I have now is a strap-on (mounts to the trunk) I bought in 1981, and those straps are starting to make me worry. If the weather stays reasonable into November, we might spend a day on the Silver Comet Trail.

Wednesday, October 21, 2020 No comments

Adventures of a #techcomm geek: Constants Aren't, Variables Won't

DITA-OT logo
One of the advantages of having a DITA-based workflow for technical writing is for translation. During the acquisition binge that ended with us being on the “bought” end, we picked up a product with a fairly strong retail presence. You’ve probably seen those products in Best Buy and similar places, and maybe even bought one to upgrade your home network. (No, I’m not going into details, because I don’t write documentation for that line… mostly.)

But, as usual, I digress. Retail products, or not-retail products that are supplied to the end-user, need to have localized documentation—that is, not just in the native language, but using country-specific idioms (although this might go a little too far). And, to help with consistency, things like notes or cautions use canned strings.

The DITA Open Toolkit (DITA-OT) PDF plugin provides a pretty good list of canned “variable” strings for a bunch of different languages, including languages with non-Latin glyphs. Of course, we added to that list… somewhat. I put quotes on “variables” because I don't know why they call them variables; they are basically language-specific constants. Local Idiom, I suppose.

Fast-forward a couple years, to the disease-ridden hellscape that most refer to as “2020.” A year ago, one of the point people for translations sat two aisles down from me, on those days we weren’t both working from home. We would have hashed half of this out in person, before roping in a bunch of other people in a long email chain. (Don't get me wrong, working remote is da bomb, and I hope they don’t expect me to do time in the office in the future… but it had the occasional upside.)

Anyway, this was the first Brazilian Portuguese translation we had done in a while, and weird things were happening. My initial guess—that we had provided updated strings for only a subset of languages (mostly French and German)—turned out to be correct, when I started poking around in the source. I remembered working on a script to parse the XML-based “variable” files to build a spreadsheet, so we could easily see what needed updating. Turns out, I had either given up or got pulled away after the script was less than a quarter-baked (let alone half). I beamed my brain power at the cursed XSLT file, and it finally turned brown and gave me the output I wanted: name[tab]value.

Now I was halfway there. I had tab-delimited files for each language, now I just needed to coalesce them into a single (again, tab-delimited) file. As I’m fond of saying, when I want to process a big wad of text, awk is how I hammer my nails… and I started pounding.

Since I had an anchor point—the “variable” names that were constant for each language—it was a Small Matter of Programming. Knowing that English (en) was the most complete language helped; I used it as a touchpoint for all the other languages. After a few fits and starts, the script produced the output I needed and I imported it into Excel. Blank cells that needed values, I highlighted in dark red. Things I needed to personally tweak here and there got yellow highlighting. I hid rows that didn’t need attention (some were complete across the board, others we don’t use), and sent it to the rest of the team.

Just to be complete, I finished the day embedding the XSLT and awk scripts inside a shell script (and tested the results). If I need to do this again, and I probably will, I can do it in a matter of minutes instead of spending an entire day on it.

I deliberately formatted the spreadsheet so I can export changes to TSV (tab-separated values) and write another script to rebuild the language “variables” if I feel it’s necessary. It’s always good to anticipate future requests and be ready for them.

Wednesday, September 30, 2020 1 comment

Taking a break

When I last talked about my remote workspace, I was adding a 40" monitor. So I got rhythm, I got music I have good lighting, lots (but never enough) of screen real estate, powered speakers I connect to my phone for music and conference calls… but not all was perfect in my homemade remote worker’s paradise.

We replaced the kitchen island a while back, and the old one is upstairs. I thought about using it as a makeshift standing desk, but that didn't materialize. Worse, it was a tight squeeze between the island and the big monitor, and Charlie banged his head on the corner of the monitor more than once when coming to visit. The only natural light is from a narrow gable, and that was partly blocked by the window A/C unit.

Mason’s fall break ran from Thursday through today, so I took the days off as well, hoping to camp down at the pond again. But with Beta coming for the weekend, bringing about two inches of rain, we decided to stay home. We tackled some of the stuff upstairs, making a little more room. I looked at the gable window, with the A/C blocking a good third of the incoming natural light, and looked at the island.

As Gru would say: “Light bulllllb.”

With an anxious Mason holding up the window, I pulled the A/C out of the window… and immediately got a bath from rainwater not quite drained out of the unit. I also found a few slits in my fingertips, compliments of my wrapping them too far around the back, but toilet paper and pressure took care of that. I borrowed a lid from a large storage tub to put the unit on as I carried it out to the garage to finish draining.

With the collected rainwater down to a few drips, I hucked the A/C out to what was once Studio FAR, but became the wife’s personal storage dump a while back. There was also a tall dorm fridge out there, plugged in but empty, so I unplugged it and carried it into the garage for a quick cleanup. There were a few drips of who-knows-what inside, but the ice buildup needed more than a couple disinfectant wipes to deal with. I got a blow dryer and started melting the ice while pulling at it with my fingers. It took maybe 20 minutes to defrost, and I dried it off and hucked it upstairs. Of course, the island + fridge were about one inch wider than the gable, but the gable outlet is switched anyway. I parked the fridge in front of the island and plugged it into a non-switched outlet.

With the break area ready, I began accessorizing. First came the coffee grinder and espresso maker from downstairs, along with the loose coffee sitting in freezers (and a pint of half&half). I ordered a 0.5l electric kettle, and a French press of nominally the same capacity, and they arrived over the weekend.

So everything was ready to go this morning, when I went back to work. That’s when I found the French press's idea of “0.5 liter” includes neither coffee nor the plunger. OK, so now I know to not fill the kettle quite full. This afternoon, I made a cappuccino for my 3pm power-up.

There will certainly be some other tweaks to the workspace, especially around the exercise equipment. But this is a big step forward. I can look out the window while I’m making coffee, and I don’t have to go back downstairs (with its potential distractions) unless I forget to bring a coffee cup along.

Saturday, September 19, 2020 1 comment

Nuke and pave

I’ve been thinking for a while that the county should either rename our road to Pothole Parkway, or stop playing whack-a-mole with the deteriorating asphalt and get serious about repaving it. And since there’s a lot of bike traffic on weekends, put in bike lanes while they repaved.

Wide and smooth
Mirabile dictu, the universe must have been paying attention for a change. The county is repaving the road… and putting in bike lanes!

Of course, before repaving, you have to de-pave. The results remind me a lot of the dirt roads when I was a kid in southwest Michigan: wide and smooth. Back then, the road commission would run a grader up and down them on occasion, then follow up with a coating of oil. Not only did it keep the dust down, it created something almost as solid as pavement. (They switched to something a little easier on the environment in the late 80s.) I remember piling eight teenagers in a VW Beetle and blasting our way down those roads at around 65MPH, trying to catch up to the people who knew where we were supposed to be going! Every once in a while, there would be a pothole, and some of the passengers would levitate for a moment.

But I digress. With Sally threatening to lay down a huge amount of rain, they panic-paved as much of the first section as they could. That was probably for the best, because the first section includes the steepest slopes (not like there’s any flat sections). We did get a lot of rain, but not the wash-out-road amounts that some were fearing, and most of it wasn’t that heavy. So the work goes on.

They started on the far end from FAR Manor, which is okay. We won’t get disrupted until the last leg. I'm hoping Mason and I will be the first to ride the bike lane all the way from north to south.


Thursday, September 17, 2020 No comments

Birthday campout

Mason turned 11 on Tuesday after Labor Day, and the wife planned a bash down at the pond (where there are a couple of pavilions, a swing set, and a large grassy area for kids to run loose in). Then she suggested I take the Starflyer down there and camp with Mason.

Hey, why not? I’ve been wanting to get out, and would have if it was just the adults. The whole thing about campgrounds, as I’ve said before, is kids take off and hang out with other kids. It’s awesome, unless there happens to be a pandemic going on. But if it’s just us…

It just popped up here, I swear…

The two-track down to the pond can be treacherous, but this time the washout was all on one side. I kept to the other side, and got it where I needed it. There’s not a 30A connection, so I couldn’t run the A/C, but there’s 15A connections and it only got hot for a few hours during the afternoon. I had fans, and zipped up the screen covers on the sunny side. It was nice and comfortable by bedtime. Sizzle opined that this was more glamping than camping; he had a cabin tent for his boys and strung a hammock for himself. I pointed out that sleeping on a mat on the ground is fine when you’re 30, even 40. At 50… not so much. At 60, forget it.

In the mornings, it was chilly enough that warming up a kettle on the inside stove was a welcome way to get the day started. I keep a French press in the camper for coffee, and Sizzle decided this wasn’t a bad way to camp after a cup or two. I also warm up a second kettle to put in the pump pot—so I have both hot and cold water at the sink for washing.

The birthday party was Sunday afternoon, and several relatives came down to join the fun. I pulled the Porta-Potti out of its cabinet and designated the camper as “the ladies room” for the afternoon. It’s a pretty low sit, so most of the women didn’t try it out. But the niece’s daughter found it perfect, and used it often. (I usually put it in the walkway at night, so nobody has to traipse into the woods in the dark, and it got used that way as well.)

Since Monday was a holiday, Skylar and the niece’s son stayed in the camper with Mason and me. The boys gave me the big end, Skylar got the drop-down bed (in which the dinette table sits on props and holds up the mattress) and the other boys grabbed the small end (and the bunk light with the fan… little rats).

I find that tearing down takes a lot longer than setup. Maybe it’s because my help evaporates, or maybe because I’m reluctant to admit it’s over. But Mason has a 5-day weekend (fall break) at the end of September. I’ve already taken vacation days—so if the weather cooperates, we’ll be back. Hopefully, the wife will join us this time.

Saturday, July 18, 2020 3 comments

Butter sauce: Easiest. Recipe. Ever.

A store-brand box of penne suggested tossing its (cooked) insides in butter sauce, so I had to have a look.

I can’t imagine a recipe easier than this, other than “Peel banana. Eat banana.” (That would be one of Charlie’s favorite recipes, anyway.) Charlie also enjoyed this with pasta (he loves him some pasta).

Ingredients:

1 stick butter (or plant butter, or margarine, whatever floats your boat)
1 T “Italian Medley” herb blend
dash (or three) garlic powder, or 1 tsp (or more… MORE!) minced garlic
1 box pasta

Do the deed:

Cook pasta according to package directions.

Melt butter in a saucepan or microwave. Stir in herb blend and garlic.

Pour over cooked pasta, toss until pasta is coated.

Serve with meat sauce and mozzarella fresca… or take your cue from Charlie and just EAT IT.

Wednesday, July 15, 2020 No comments

Backyard retreat 2.0 (patio to pool)

Ever since we put the gazebo up in the front yard, the old backyard retreat has languished. The fire bowl in the table rotted out, and I’ve procrastinated on rebuilding it. The cushions on the chairs got kind of grotty, and somehow a table (sans top) made its way down there. The rubber tiles were still mostly in place, although a few got scattered out.

But summer + two boys + a pandemic that will probably last through next year got me thinking. We had a small (6') inflatable pool from last year laying around… it had been put up wet, but it still held air and water. We cleaned it up as best as we could and put it on the sidewalk out front (level spots around Sector 706 in general, and FAR Manor in particular, are hard to come by).

All well and good for the kids, but what about the parents? Some poking around Amazon turned up several candidates. So… where would we put it? We need something mostly level.

Oh. The old retreat. But I didn’t want to just drop the pool on the bare ground… the soil around here grows rocks, and I figure it wouldn’t take long for a sharp rock to punch a hole in the floor. The elder sister in law had an above-ground pool at her old place, and fire ants chewed through the floor when the rocks wouldn’t do the job, so “slap directly on ground” was right out.

My first thought was to build a low deck, but I calculated the pool would weigh about 5 tons. I overengineered a deck at our old place, but I don’t know if even it would have supported that much weight. We then considered pouring several inches of sand into the space, or even concrete, to get a flat surface. Given the location, there would be a lot of grunt work involved with concrete: we would have to either carry 100 bags down there, mix it and pour it, or find a concrete company who could maneuver a truck up the driveway and send the slop down a chute. Seeing as I simultaneously tweaked my back and horked my (supposedly good) knee last week*, ironically while bailing water out of the small pool, paying to have someone else do the grunt work would have been the best idea.

Finally, we decided it would be best to smooth out what we have now, cover the Envirotiles with a tarp to protect the pool from ant attacks, and cover it with a pergola.

Patio area, cleared. (Phase 1)
So I took the boys down to the patio Sunday afternoon, and we got everything moved out. Charlie did his best to help, picking up a plastic chair and dragging tiles over to our stacking area. Mason was less enthusiastic, but did a lot of the work. I raked out remaining debris, and tried to level out high spots. I sprayed the whole area with Roundup to discourage plants from trying to slip between the tiles… but, as it turned out, most of the growth was in composted leaves that hadn’t been swept away in a long time.

Given the pandemic, large pools are going for a premium. We ordered a round 10' pool (with filter) for $300, and the same pool was going for $100 pre-pandemic. But even at COVID prices, the pool itself is the least costly part of this project.

The pergola, at $1600, is actually the priciest component. Wayfair is now telling us it won’t be delivered until August (after saying it was in stock when the wife ordered it), but August is when we'll need it most.

The boys laid tiles.
And did a pretty good job of it.
Next step: smoothing out the dirt. Nine years of rain, frost, erosion, and roots had lifted some spots and sank others (most of the sinking was along the south edge, where things do drop off). Last month, Mason and I replaced the rotten fascia boards across the front of the detached garage. One of the original boards was still good, for most of its 16-foot length, and it’s nice and straight.

We dragged it across the dirt to catch high spots, and I scraped them down with a shovel and tossed the dirt into low spots. It’s not perfect, but more effort won’t be worth the return. I swept dirt off the tiles, handed them to Charlie, and he carried them to Mason, who put them in place. Both of them were a big help—but of course, both of them want the pool going!

With the tiles down, I put the tools back in the garage and got out the leaf blower. There were leaves around the margins, and dirt on the tiles (kicked up when I frisbee’d a few tiles down to Mason).

Just add tarp (and pool… and yes, water). (Phase 2)
At this point, we just need to get a 10x10 foot tarp to lay over the tiles, then we’ll be ready to put the pool in place and start filling it. I estimated we’ll need about 1400 gallons to fill the thing—in other words, we won’t be able to fill it all at once. I’m thinking about tapping the downspout on the rain gutters, running a flex-pipe down to the pool, and catching any debris with screening… or seeing if bulk water delivery is reasonable.

I figure we’ll be able to use it through September this year, and all summer next year. Once the pandemic is over, we’ll still have the option of not driving 15 (or 40) miles to go to a pool.

Stay tuned for the completed project!

Are you restructuring your yard for an extended shelter-in-place? Comments, as always, are open!


*Both back and knee are around 90% of full-function right now, which is a dangerous zone. Just because they’ve subsided to a low-level ache, instead of stabby OUCH pain at random (all too short) intervals, doesn’t mean you can safely hoist 60lb bags of concrete at will… even if you think you can. My back is letting me know I was pushing my luck just cleaning off tiles this evening.

Monday, July 13, 2020 No comments

Oh deer! (redux)

Somehow, we as a family have been fortunate when it comes to deer encounters. This one marks the third occasion that a deer and one of our cars have attempted to occupy the same point in space, without damage to (at least) humans and vehicles.

Last week (Monday, of course), Daughter Dearest was heading back from the church to her house. Just beyond the church driveway, of course… a doe and its fawn decided to play a live-action version of Crossy Road, using DD as an NPC. Unlike non-players in Crossy, DD stood on the brakes, and the doe scooted on by. The fawn… not so much.

There, there…
Fortunately, at this point, she was going slow enough to bonk the fawn and tumble it a few times. For all her ferocity with people, DD has an extremely tender heart when it comes to animals. So she gathered up the four-legged victim (which was unable to get its own act together) and carried it up to the church porch.

From there, she called her mom (totally upset), then the DNR. The latter was busy trying to deal with a bear keeping someone in her car* so the two of them sort of comforted each other while Wildlife Rescue got its act together.

The DNR people got there, and assured DD that the fawn wasn’t severely damaged—no broken back, at least. With any luck, they’ll fatten it up for Thanksgiving dinner reunite it with its mom shortly.

Of course, wife and I were concerned first with DD, and then with her car. Both were fine. Wife opined: “She can hit a deer and not have any damage, but hitting a groundhog tore out half the underside of the car!” Well, this is Sector 706… logic is neither common nor appreciated.

*Probably not the same bear I encountered Friday night. That one has been sneaking up to the manor, on dark nights when we forget to drop the garage door, and gobbling an entire 40lb bin of dog food. I happened to be on a late-night grocery run, and probably startled him off as I pulled up the driveway, since the bin was just outside the garage. Turning on the floodlights, I saw him standing there on all fours in the back yard. After I cussed him out and banged on the plastic garbage bin (empty because of him), he shuffled into the woods. The dogs, who usually lose their shorts when a strange car comes up the driveway, amazingly didn’t say boo about a freeking bear coming up to visit. Then again, as I’m fond of saying, “stupidog” is one word.

Tuesday, June 30, 2020 1 comment

Impending: screen tan

I’ve been plugging along in my new work space for a couple of months, now. A couple weekends ago, while taking some time off, I did turn the light fixture 90° as threatened, and my gorgeous face is now lit up much better during videoconferences. :P

One thing that has chafed me about the homegrown workspace… I had two large monitors at work, side by side. At home, I had the laptop screen and a 17" NEC monitor that Solar gave me a few years ago. The work monitor mount was integrated with the cube/desk, and I didn’t have the time or inclination (at the time) to figure out what to do with them. I’ve made do, but wanted a little extra.

I am SO buying these socks for her.
Well… let me preface this by saying I’m not trying to criticize in any way. We all have our own ways of coping with the pandemic (not to mention The Boy checking out in August), and maybe her watching the Hallmark Channel for hours on end is healthier than me sitting at the computer and drinking myself stupid most nights.

Anyway, The Boy left us a 40" Sony TV. Wife wanted to upgrade our 32" Samsung for a while, and got someone to swap TVs for her when I was occupied doing something else (i.e. upstairs working). All well and good, except that the Sony’s HDMI2 input was boogered somehow. We used HDMI1 for the satellite connection, and #2 is the DVD player. We would see the DVD player's startup screen, then it would go black and not respond to pretty much anything but an input change.

Long-time readers know that the wife’s idea of troubleshooting is to go for the most expensive/time-consuming fix. Without my knowledge or input, which is fine if she used her own money, she bought another 40" TV. A Vizio, this time, which is fine. I don’t exactly trust Sony to keep its mitts out of my LAN. But I digress. There was something about a new wall-mount involved, and I dragged out the tools.

A while back, someone left a DeWalt driver/drill at the manor, with a 20V battery. I bought a charger and a spare for it, and I’ve used it for a couple of two-minute projects… then the parsonage’s back deck needed resurfacing. I brought it along, and it tore through that job like it was SARS-COV-2 tearing through immunocompromised lungs.

But I digress. The driver also made quick work of the wall-mount, and the Vizio was playing Hallmark movies in well less than an hour.

BIG screen!
That left me with an extra screen, a need for it, and a specific set of circumstances. The old wall-mount was great for the living room corner, but I needed something that went sideways from a wall, over my desk. Dragging out the measuring tape, I found that 18"-24" would give me plenty of clearance. Off to Amazon I went, quickly found a wall-mount arm with 24" of clearance, and ordered it. It arrived today, and I hucked it and the toolbag upstairs.

It took longer to mark the holes than to drill pilot holes, and to drive the bolts into the studs. It makes SUCH a huge difference to have good tools. In a manner of minutes, I hung the monitor on the mount, routed cables, and plugged everything together. The laptop’s dock has an HDMI connection, and I happened to have a stray cable laying around… presto, a humongous 1920x1080 monitor!

Maybe now that I have the hardware in place, the employer will spring for a 4K monitor… ha. I'm trying to decide whether to return the 17" NEC monitor to my bedroom desk. It might be useful for side jobs. After all, you can’t have too much screen real estate.

Monday, May 25, 2020 1 comment

To disc, perchance to golf

I was tempted to file this one as pandemic-related, but it was more of a “last straw” thing than a completely isolation-related incident.

Disc golfing has been around for a while. I remember going to a park in Grand Rapids, with Other Brother, when we were either nearly done with high school or just starting college (so, 1977, give or take a year or two). Back then, everyone called it “Frisbee golf” and played with backyard discs. The goals were usually posts that you tried to hit with your disc.

Portable goal
I enjoyed it, but college, a move to Planet Georgia, and doing other things caused me to lose touch with the sport. It was only after I went to see The Boy in Manitowoc that I started to reconnect. One of the parks has a disc golf course, and he had taken it up. We got me a disc (there was a shop near the park that sold a variety) and had a blast. By then, of course, the official goals (or holes) were now baskets with vertical chains, like in the pic here. Except, of course, actual courses have their goals sunk into the ground to prevent mischief.

The vagaries of life kept me from taking it up much, partly because I didn’t know of any nearby courses. But when The Boy returned to Planet Georgia, he quickly found two courses 15 and 25 miles away. I bought a “starter pack,” four discs with varying flight characteristics and a carry bag, and I added my Manitowoc disk to the collection. When The Boy took his longest journey, Mason (who also likes to disc golf) and I got his bag. Mason has mostly taken it over, but I picked out one or two to round out my set.

Backyard goal
Now, with parks closed (or if they aren’t, it’s still iffy to go), I decided it was time to work with what I have—a large-ish yard with lots of obstacles—and ordered a pair of goals. I put them at opposite corners of the house, and chose some tee-off spots. I have a four-hole course: the first two counter-clockwise around the house, the second two clockwise.

The course, given the limited space I have to work with, rewards accuracy much more than raw power. Tee shots require threading a needle between trees, bushes, and the house. I’m getting noticeably better.

Going online, I’ve also learned a little about flight characteristics, and what to expect from a disc when you throw it. That has improved my game as well. Now I can step outside at lunch and throw two or four holes, depending on time constraints, and then play a little more once I’m done for the day.

Weather permitting, of course. It has been raining a lot in the last couple of months.

Friday, April 24, 2020 2 comments

Life and Work in the Time of Pandemic (part 4, workspaces)

Planet Georgia's sorry excuse for a governor partially lifted the shelter-in-place, starting today. That’s going to have consequences in late May, for sure. Nevertheless, we got an email from work that said, in effect, “yeah, we know, keep working at home.”

Things I needed to set up a workspace arrived this week, and I found some other necessities in the garage. So after I sent my reports this afternoon, I got to work. After clearing the space, I vacuumed the (horrid) carpet.

We’ve been using The Boy’s old room for storage for a while. Clearing out a corner wasn’t all that difficult, but lighting has always been an issue. The house is a Cape Cod, and the only window in each upstairs bedroom is in the gable. I ordered a 4-foot LED fixture and power cord, and mounted it on the sloped part of the ceiling. Plugging it in yielded plenty of light, enough for most of the rest of the room. I used an old wire shelf hanger hook to keep the cord up against the wall.

Now for the furnishings. Daughter Dearest’s old office chair was sitting in that corner, and I found an old typing desk in the detached garage. Of course, it was all the way to the back, and covered in stuff (including lots of dust and grime). Fortunately, it was light enough for me to lift and carry by myself, and I hucked it across the driveway before wiping it down. I really need to hit the metal parts with a wire brush and repaint it, but that can wait.

With the desk mostly cleaned up, I hucked it up the stairs and dropped it in place. I grabbed the bag of gear (dock, keyboard, mouse) that I got from the office back when they first told us to not come in, and took that upstairs. To my delight, there was also a power strip that I’d forgotten about. Finally, the laptop and my second monitor went on up to make the final connections.

Another garage find—a big monthly planner whiteboard—was the last piece. We have a little container of picture hanger hooks, and there was a length of wire as well. I put it together, and there was already in a screw in the wall at just the right height. Incidentally, it covers a bunch of marks, so it wins twice.

It’s not quite done yet, even if it’s usable as a workspace in its present state. I plan to put some hooks under the front of the desk to neaten up the cabling, for starters.

Longer term, the wife wants to replace all the carpeting in the room and paint the walls. When that happens, I plan to use whiteboard paint at least in that corner. Maybe I’ll replace the cord with house wiring, to get it out of the way.

Come Monday, I’ll be a lot more comfortable about turning video on for our many conference calls than I have been in the past. I could also put pithy messages like “Approvals needed ASAP” on the whiteboard behind me, to enhance my presence.

Thursday, April 09, 2020 2 comments

Life and Work in the Time of Pandemic (part 3, school)

We’re on spring break this week… like I said in the last post, we were supposed to be at the beach, but having to cancel a vacation falls into the #firstworldproblems bucket.

The two-week “online learning” got extended to next week… then just before break, they finally realized the wisest course was to finish out the school year online. It’s a pain in the rear, but better that than getting a bunch of people sick without need (or the resources to take care of them).

I need to say, the school system obviously meant the whole online learning program to be something used once or twice over the winter, maybe for a few days. Now they’re having to adapt it for a months-long outage. My biggest beef with it is that they couldn’t settle on a single app or website to manage everything—there are three or four apps/sites, and they occasionally roll out another one. Although my Mac has a built-in password manager, I’ve gotten account fatigue over the years. So every time I get a memo about Yet Another Account to set up, they can hear my eyes rolling all the way out here.

“Out here” presents its own online learning issues. This is farm country, and I still think it’s amazing we have DSL. It usually works OK, unless heavy storms take out a line card (which happens pretty often)… or everybody who can work at home is doing just that and their kids are also online trying to do their schoolwork. It gets where the connection can’t even support a low-bandwidth music stream. I can do the normal work things—email, edit a DITA file from the cloud, chat—because that traffic is mostly short bursts and can slide in between the school traffic. Conferences are more iffy, but I usually use my cellphone for audio and the video is showing mostly static images of spreadsheets or documents.

But I digress. Our school is swimming against the Zoom current (an app I only heard about after the isolation began) and using Google Meet (aka Hangout). We can often manage one hangout at a time, or at least phone in if bandwidth is an issue. Charlie’s therapists (and pre-school) is also using Meet. Most of the time, this seems to work out. The bandwidth is hitting Daughter Dearest even harder, because she’s a teacher and has to be online. It got so bad that she simply bypassed the wheezing DSL and used her phone to get out. Needless to say, that burned through our data cap, our reserve, and then some. Now we don’t have a cushion for this month. I suggested she go to Dunkin', get a coffee and maybe a doughnut from the drive-thru, then sit in her car and scarf the Wi-Fi from there.

Often enough, our connection is marginally good enough, so DD and her kids have been at the manor most school days. That means I’ve had AJ (or Charlie) in my lap more than once during a conference call. I can totally derail a meeting by turning on my camera with either one; they’re both cute.

While we’re on break, I’m trying to set up a place in the larger upstairs bedroom (The Boy’s old room) as an office space. We made some headway yesterday. But I can’t help but think that once I get upstairs, all the kids will wander (or be sent) upstairs so I can still deal with something. I guess that’s okay, as long as I hold my end up at work. So far so good!

How about you? Have you torn a bumper sticker off your van yet? Comments are open!

Wednesday, April 08, 2020 No comments

Staycation, pandemic-style

We were supposed to be in Florida this week, hanging out with Mom and hitting the beach. Instead, we’re at FAR Manor.

Over the weekend, I finally got the new front derailleur on the Fuji dialed in. Hooray, time to take a ride! Um, no. The rear inner tube had partly separated from its stem. Well, Solar had suggested I put wider tires on it to improve the ride, anyway. There’s not a lot of clearance at the front fork, but thought maybe I could go from the current 25mm width to 32mm. I have a pair of 47mm tires, but they’re definitely too wide and the wrong diameter anyway. So I made plans to run over to the bike shop on Monday, and maybe get Charlie a bike with training wheels. Meanwhile, Skylar’s bike (the one he has here) needed shifting and braking adjustments. I got him rolling as well.

In the vein of “don’t go out unless you have to,” I called the bike shop before going. Nope, the shop guy opined, there’s not enough room. And they didn’t have any Charlie-sized bikes in stock. I thought we had a small frame laying around, so instead of driving to another bike shop I thought I’d try to Frankenstein a bike from bits and pieces.

Needs a little cleaning along with training wheels
Instead, I found an entire bike with a 12” frame! It was one Mason had for a while, until he outgrew it. The tires, amazingly, still held air. Some WD-40 got the chain loosened up, and I regreased the bearings on one wheel. So it rolls, it pedals, and the coaster brake works. I ordered a set of training wheels, and almost added a Trailgator (basically a towbar to pull his bike behind mine). The price—$65 for a metal bar with clamps on either end—put me off, though. Anyway, I raised the seat an inch and it fit Charlie perfectly.

All that, actually, was in between the ceiling fans. Daughter Dearest had ceiling fans for each of the kids’ rooms (three in all), and asked me to put them in because Sizzle is still working while the rest of us are on spring break. I succeeded, only after multiple trips back to the manor to fetch hardware, tools, and at last I had enough and brought everything. That turned out to be the way to go, and the fans are all happily spinning away.

I mentioned Skylar… he’s been spending weekdays at the manor because his nominal guardians are both working. He brought his bike up (the one I adjusted) over the weekend, and an HP laptop. “Do you have a cord for this?” he asked, repeatedly, until I told him to knock it off and let me do it when I had a chance. Before the fans, I scrounged a power cord and had to shave a little off the female end to make it fit in the power supply. I pushed it in, using as much force as I dared, and a light came on when I plugged it in. He wanted to start it right away, of course, but I told him to give it a few hours to let the battery get charged.

Finally, after everything, we started it. Black screen, and the Caps Lock LED was flashing. I realized it was a pattern—three long, two short—and I looked it up. Memory error. “Well,” I told myself, “it hasn’t been run in a while. Maybe if I reseat the RAM, it will be OK.”

So I flipped it over, opened the little door on the bottom, and… no RAM at all! I found out later, from Skylar, that a house guest had scrounged the single memory stick to put in his own computer. Nice guy. So I couldn’t reseat the RAM, but I had a 4GB stick on my desk from when I upgraded the iMac. It looked to be the same style, so I used the “cat in a box” formula: if it fits, it sits. I buttoned it up, plugged it in, and hit power. It coughed to life and displayed a login screen for the Microsoft thing. Yuck. Of course, I didn’t have the PIN it requested, although I tried some of the common ones (1234, 9999, etc). I configured the BIOS to boot from a USB drive, stuck one on and rebooted, and I soon had a Kubuntu desktop. Things seemed to be working properly, and exploring the hard drive suggested there was little or nothing (besides the OS and apps) on it. Skylar thinks his grandfather (Big V’s widower) knows the PIN, so he should soon be off and running.

So that was my first day of staycation: mostly fixing other people’s stuff. But I’ll soon have a new inner tube for the Fuji, and I’ll at long last take it on its shakedown cruise.

Wednesday, March 25, 2020 No comments

Life and Work in the Time of Pandemic (part 2, food)

Coronavirus (image credit: CDC, public domain)
Our “online learning” was extended through Spring Break, the first full week of April here, and they should probably close out the school year doing it. I suggested that to Daughter Dearest, and her response was “SHUT UP. SHUT UP.”

But whether we pull a Hong Kong and lift restrictions early (spoiler alert: it would be a Bad Move), or keep movement tamped down to prevent further spreading, the occasional grocery trip is a necessity. Maybe less necessary is occasional pickup from restaurants, although they might argue the “less necessary” part.

Restaurants are adjusting as well as they can, offering incentives like extra points for rewards programs or free delivery. Meanwhile, the wife and I have roughed out meal planning. We’re mostly digging meat out of our freezers, although we're short on ground beef and the hoarders (aka #covidiots) grabbed it all last weekend. Bread and milk are easier to find, now… both have a finite shelf life and hoarders might have a hard time using what they have before it spoils. Ground beef should soon be available as well, because even covidiots have only a finite amount of freezer space. (But they must be using all that toilet paper as mattresses.)

Meanwhile, the school system is still running the bus routes… except instead of dropping off kids in the afternoon, they drop off lunches in the late mornings. We don’t need the extra food, but they beg us to take it because we’re at the end of the route. Today, we got burgers. The kids eat whatever sandwiches are provided, but sometimes skip the veggies + ranch dip packages (add 1/4 tsp of onion powder to the ranch containers, instant chip dip). We’re going to cook the veggies for supper, if I keep my mitts out of them. Still, it’s starting to get overwhelming—we’re covered up with fruit, milk, juice, etc. We’ll need to make sure the neighbors get some of this if it continues.

Since the kids don’t drink all the milk, I have rediscovered the joy of drinking half-pints of chocolate milk from the carton. I have not yet tried my old trick of jabbing the side with a pencil, making a hole of the exact diameter of a straw; I could pressurize the carton and pump the milk into my mouth. One of my better memories of elementary school.

Fortunately, Charlie is expanding his protein sources, although he still strongly prefers his latest adoptions to be breaded and fried. Chicken nuggets (especially Chick-Fil-A) and fish sticks are winners. We thawed and baked a slab of salmon I had kicking around in the freezer earlier this week; the adults ate that, and Mason and Charlie gobbled several helpings of sticks. We got these corn dog bites, and Charlie ate half of one before he realized it wasn’t chicken, then ate the breading and left the mystery meat. Sometimes, it’s hard to tell the difference between picky and intelligent.

We have a few days of not-rain this week (yay!) so I’ll likely pull some ribs out of the freezer and smoke/grill them.

Monday, March 16, 2020 2 comments

Life and Work in the Time of Pandemic (part 1)

Coronavirus (image credit: CDC, public domain)
Local schools are on “online learning” this week (and I’m sure that will be extended). I started working from home last week, and we all got a “recommendation” from a manager to work at home through March 27 (again, it’ll probably be extended). Oddly enough, Charlie’s daycare (a Petri dish if I ever saw one) is remaining open. His therapy office is also open, but they’ve moved the waiting room out to the parking lot… in other words, wait in your car until your therapist comes out. Our little church has moved its sermons online (unfortunately, to the Book of Face, which I don’t use) for the duration.

You’re probably seeing the same things in your locale, and I’m not here to provide dry statistics. I’m going to journal the mostly self-isolated life in a rural area, in case someone else finds it interesting now or later on.

Long-time readers might remember FAR Future, a long blog-novel I wrote starting all the way back in 2007. Although the chronic energy shortages that the whole story is built around have yet to materialize, some of the things I wrote about have had eerie parallels in real life. One episode (written in Sep 2008) discusses a serious flu pandemic, with a 3%-5% mortality rate, breaking out in… December 2019. We’re not laboring under a junta, but the administration in real-life 2020 is every bit as incompetent as was the junta in FAR Future. The difference is, the fictional flu was like the 1918 pandemic, hitting young and healthy adults the hardest. This one goes (mostly) after the elderly. We also have the Internet, a find way to find information (and plenty of misinformation) about what’s happening.

Saturday was “run errands” day, so I combined the trips to limit time out and contacts. Charlie had horse therapy, and we needed both some groceries and a UPS battery. Other than that, we were in all weekend. Wife and I keep talking about meal planning, so we can order pickup from the local Kroger, but haven’t quite done it just yet. Today, she’s out with Charlie for therapy. I’m not sure he’ll go to daycare today. If he does, I might run to the office to grab a laptop dock and some notes, then pick him up on the way back.

These first few days of (mostly) shelter-in-place are very strange. It’s like a winter storm, except that all the utilities are working and the roads are even more clear than usual. Our crappy DSL is crappier than usual, what with all the school kids with Internet doing their work online (not to mention people like me, trying to work). Structure is going to be important… along those lines, Daughter Dearest forwarded me a suggested schedule for families. Modify as needed, but a little structure will make everyone's day go better:


Meanwhile, I have a minor cold. I’ve never been so glad to sneeze.

Tuesday, March 10, 2020 No comments

Adventures of a #techcomm Geek: Match Game, 2020

It’s been a while since I did one of these, and this one goes in deep.

We’ve been using DITA at work for a year or two now, but rarely is there time to go back and take advantage of the things it offers, retrofitting those things into the documentation we brought in. (Docs we’ve created since then seem to get more thorough treatment.)

One of those things is reuse. It’s easy to reuse an entire topic in a different book—even if it was duplicated. “Hey,” says a writer, “that’s the same thing. Let’s throw away topic B and use topic A.”

DITA also supports reusing common paragraphs in two or two dozen topics, but that’s a little harder. First, you have to recognize that paragraph. Then, you have to create a new topic (a collection file), copy the paragraph into the collection file, and assign it an ID. Then you have to replace the duplicated text (in topics) with a content reference (a/k/a conref). It’s a worthwhile thing to do, because you might say the same thing slightly differently otherwise. Still, who wants to go through an entire book (or worse, set of books), looking for reuse candidates?

Of course, you can always let a computer do the tedious work… if you know how to tell it what to do.

Preparing the (searching) grounds

A while back, I wrote my first useful Python scripts. One takes a particular JSON file and reformats it as a DITA reference topic, containing a table with the relevant data from the JSON file. Another walks through a CSV file, grabbing the columns I need, and producing topics documenting a TR-069 data model. Both scripts take advantage of a vast library of pre-written code to parse their input files.

It occurred to me that, if I were to find (or create) a way to export all the text from a DITA book into a CSV file, I could use a Python script to compare each paragraph to all the others. Using fuzzy matching would help me find “close enough” matches. That was a while ago, because I bogged down on trying to get properly-formatted text out of DITA.

Last week, I got bored. Someone on the DITA-OT forum mentioned a demo plugin that translated DITA to Morse code, and the lightbulb in my head went on. If I could modify that plugin to just give text instead of -.-. .-. .- .—. then maybe I’d have what I needed.

It was an abject failure. What I need is one line per block element (paragraph, list item, etc). What I got was one line for the entire topic, sometimes with missing spaces. I put that aside, but realized that DITA-OT can also spit out Markdown. If I could convert Markdown to plain text, I’d be ready to rock!

So you want to convert DITA to Markdown? It’s easy, at least with the newer toolkits:

dita --format=markdown_github --input=my.bookmap --args.rellinks=none

The DITA-OT output continues to be topic-oriented, writing each topic to its own file. That wasn’t quite what I wanted, or so I thought at the time. Anyway, we have Markdown. How do we get plain text out of it, with each line representing a block element?

Turns out that pandoc, the “Swiss Army knife for converting markup files,” can do it:

pandoc -t plain —wrap=none -o topic.txt topic.md

In the heat of problem-solving, I realized I didn’t need a CSV file… or Python. I could pick up Awk and hammer my nails the text into shape. My script simply inhaled whatever text files I threw at it, and put all the content into an array indexed by [FILENAME,FNR] (FNR is basically the line number of paragraphs inside the file). There was a little stray markup left, not to mention some blank lines, and a couple of Awk rules threw unneeded lines into the mythical bit bucket.

Got a (fuzzy) match?

A typical match is an all or nothing Boolean: you get true (1) if the strings are an exact match, or false (0) if they don’t.

Fuzzy matching uses the universe of floating-point numbers in between 0 and 1 to describe how close a match is. It’s up to you to decide what’s close enough, but you usually want to focus on values of 0.9 and higher. And yes, an exact match still gives you a score of 1.

Why do we want to do this? Unless content developers are really good about cutting and pasting in a pre-reuse environment, inconsistencies creep in. You might see common operations described in slightly different ways:

Click OK to close the dialog.
Click OK to close the window.

So along with flagging potential reuse candidates, a fuzzy match can help you be consistent.

Python and Perl have libraries devoted to fuzzy matching. There are several ways to do a fuzzy match, but one of the more popular is called the Levenshtein distance. There's a scary-looking formula at the link, but it boils down to single-character edits (addition, deletion, or replacement). The distance between “dialog” and “window” is 4 (d→w, a→n, l→d, g→w).

But this is an integer, not a floating-point number between 0 and 1! But that’s easy to fix. If l1 and l2 are the lengths of the two strings, and d is the calculated Levenshtein distance, then the final score is (l1+l2-d)/(l1+l2). In the above example, the score is 0.93—the strings are 93% identical.

There are websites with Levenshtein distance implementations in all sorts of different programming languages, although the ones written in Awk are not as common. But no problem. Awk is close enough to C that it’s simple to translate a short bit of code. I picked the second of these two. There was one already written in Awk, but it took a lot more time to grind through a large set of strings.

Save time, be lazy

The time it takes is important, because it adds up fast. Given n paragraphs, each paragraph has to be compared to all the rest, so you have n2 comparisons. A medium sized book, with 2400 paragraphs, means 5.76 million comparisons. Given that a fuzzy comparison takes a lot longer than a boolean one, you want to eliminate unnecessary comparisons. A few optimizations I came up with:

  • It’s easy to get to (n2-n) by not comparing a string to itself. We also do a boolean compare and skip the fuzzy match if the strings are identical. Every little bit helps. Time to analyze 2400 paragraphs: 2 hr 40 min. My late-2013 iMac averages about 600 fuzzy match comparisons per second.
  • By deleting an entry from the array after comparing it to the others, you eliminate duplicate comparisons (once you’ve compared A to B, doing B to A is a waste of time). That eliminates noise from the report, and cuts the number of comparisons required in half. Time to analyze 2400 paragraphs: 1 hr 20 min. Not bad, for something you can do with one more line of code.
  • Skip strings with big differences in length. Again, if l1 and l2 are the lengths of two strings, then the minimum Levenshtein distance is abs(l1-l2). If the best possible score doesn’t reach the “close enough” threshold, then you don't have to do the fuzzy match. Time to analyze 2400 paragraphs: 5 min 30 sec!!! Now that’s one heck of an optimization!

So we’ve gone to something you run overnight, or at least during a long lunch break, to something that can wrap up during a coffee break (eliminating 96.5% of the time needed is a win no matter how you look at it). Now if your book is all blocks of similar length, it will take longer to grind through them because there isn’t anything obvious to throw out.

Still, this is down to the realm where it's practical to build a “super book” (a book containing a collection of related books) and look for reuse across an entire product line. That might get the processing time back up into the multiple-hours realm, but you also have more reuse potential.

Going commercial

The commercial offerings have some niceties that my humble Awk script does not. For example, they claim to be able to build a collection file (a “library” of sorts, containing all the reusable paragraphs) and apply it to your documentation. That by itself might be worth the price of entry, if you end up with a lot of reuse.

They also offer a pretty Web-based interface, instead of dropping to the command line. And, they have likely implemented a computing cluster to grind through huge jobs even faster.

But hey, if you’re on a tight budget, the price is right. I’m going to make sure the employer doesn’t have a problem with me putting it up on Github before I do it. But maybe I’ve given you enough hints to get going on your own.
UPDATE 10 May 2020: The script is now available on Github.

LinkWithin

Related Posts Plugin for WordPress, Blogger...