HTML5: Text to speech

HTML5 includes some text-to-speech processing that can be invoked via JavaScript. I wrote a quicky script to allow you to paste text and have it read for you. It's great to proofread emails before you send them.

Leave A Reply

Web based bandwidth converting tool

I was ripping DVDs and needed to calculate the final output size given a specific bitrate. I got tired of doing the math over and over so I wrote a tool to do it for me.

Bandwidth converter

Leave A Reply

Linux: Find command with "or"

Linux has a very powerful find command, but it can be daunting to get all the options right. Recently I needed to find all my new .txt and .pl files. To do this you need to be able to say "find all the files that are text OR perl". In Linux find that looks like:

find /dir/path/ -type f \( -name '*.txt' -or -name '*.pl' \) -ctime -7

The spaces after and before the surrounding parenthesis are required or you will get weird error messages. Lots of research and examples borrowed from geeksforgeeks.org.

Leave A Reply

NPR has a great audio quality comparison test

NPR has an amazing quiz for various bitrates of compressed audio. It will test to see if you can hear the quality difference three different bitrates: 128Kb/s, 320Kb/s, and uncompressed. I've taken the test several times and I'm unable to hear the difference for anything above 128Kb/s. I even used headphones to get the best experience and it didn't help.

Leave A Reply

Perl: Nested subroutines

Perl doesn't support nested sub-routines natively, but you can fake them by using functions defined at runtime.

sub a {
    local *b = sub {
        return 123;
    };

    return b();  # Works as expected
}

b();  # Error: "Undefined subroutine &main::b called at ..."

Some times nested functions can be useful for simplifying readability of code while also allowing simple copy/paste for code re-use.

Leave A Reply

Books of 2021

List of books I read in 2021. Also see the list of 2020. The date indicated denotes the date I started reading the book.

2021-01-01 - Ready Player Two - 366 pages
2021-01-06 - The Institute - 561 pages
2021-01-14 - Turtles All the Way Down - 286 pages
2021-01-19 - Mindfulness In Plain English - 196 pages
2021-01-22 - Catcher In the Rye - 214 pages
2021-01-26 - The Odyssey - 303 pages
2021-02-01 - Ringworld - 342 pages
2021-02-07 - The Ringworld Engineers - 354 pages
2021-02-16 - The Ringworld Throne - 352 pages
2021-02-21 - Ringworld's Children - 284 pages
2021-02-26 - Protector - 218 pages
2021-03-01 - Arguing with Zombies - 414 Pages
2021-03-08 - Desperation - 690 Pages

2021-xx-xx - Regulators - 475 Pages

2021-xx-xx - Hitchhiker's Guide to the Galaxy - 209 pages
2021-xx-xx - The Restaurant at the End of the Universe - 217 pages
2021-xx-xx - Life, the Universe, and Everything - 182 pages
2021-xx-xx - So Long, and Thanks For All the Fish - 204 pages

Leave A Reply - 1 Reply

Proxmox: Disable registration popup for 6.3

To disable the registration popup on Proxmox 6.3 run the following command:

perl -0777 -pi -E 's/if \(res === null \|.*?\) \{/if (false) {/s' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
Leave A Reply - 1 Reply

Perl: Slurp entire file in a one liner

I need to change some text in a file that's spread across multiple lines. This means perl -pE won't work because it treats each line as a separate regexp. Reading the file in to one big string and then running a multiline regexp is the best solution.

Using -0777 tells Perl to read the entire file in to one string and allows multi-line regexps to work as intended.

If you have an input file with the content like:

if (foo
    && bar && !true) {
    # Do stuff
}

You can change the if statement with a one-liner like this:

perl -0777 -pE 's/\(foo.*?\)/(test)/s' /tmp/input.txt
Leave A Reply

Eagleson's law

“Any code of your own that you haven't looked at for six or more months might as well have been written by someone else.” - Eagleson's Law

Seems about right.

Leave A Reply

Bash: Using previous command's parameters

Bash allows you to save some typing by referencing the previous command's parameters via a variable. If you want to reference the first parameter from the previous command you would use !^ and if you want the last parameter you would use !$. A real world example would be something like this:

mkdir /long/dir/structure/new_dir
cd !$

This would make a new directory and then change to that directory. Alternately you can reference numbered parameters using !:2 to reference the 2nd parameter.

Leave A Reply

Apache: Blocking access to certain file types with .htaccess

My templating system uses .stpl files for it's definitions. I do not want to serve these files directly to my users so I used an .htaccess file to block them.

<Files ~ "\.stpl$">
    Order allow,deny
    Deny from all
</Files>
Leave A Reply

PHP: Look in to a multi-dimensional array using array_dive()

I have a multi-dimensional array that I need to extract data from. Given a string in the format of "person.first" I want to descend in to the array looking for person -> first. I wrote this array_dive() function to facilitate this lookup.

function array_dive(string $needle, array $haystack) {
    // Split at the periods
    $parts = explode(".", $needle);

    // Loop through each level of the hash looking for elem
    $arr = $haystack;
    foreach ($parts as $elem) {
        //print "Diving for $elem<br />";
        $arr = $arr[$elem] ?? null;

        // If we don't find anything stop looking
        if ($arr === null) {
            break;
        }
    }

    // If we find a scalar it's the end of the line, anything else is just
    // another branch, so it doesn't cound as finding something
    if (is_scalar($arr)) {
        $ret = $arr;
    } else {
        $ret = null;
    }

    return $ret;
}

Here is a sample script that shows the function in action.

Leave A Reply

Smarty: E_NOTICE warnings on undefined template variables

After upgrading my PHP and Smarty installations I started getting E_NOTICE warnings for any template variable that was not defined. There are valid reasons to have an undefined variable in your template, so I did not want to show a notice every time one is encountered. A real world example that I've encountered is:

{if $debug}
    Debug: {$error_string}
{/if}

One could argue you could just test if $debug is non-empty, but that's more typing and feels redundant. I have a lot of old templates using this sysntax and didn't want to have to update all of them. The simple solution I found in the Smarty README.

// Don't show missing template variables as E_NOTICE
$smarty->error_reporting = E_ALL & ~E_NOTICE;

Note: This does not mask your normal PHP E_NOTICE errors, just ones generated by Smarty.

Leave A Reply

Perl: Named captures in regexps

In a regular expression you can capture strings into variables using the default syntax:

$str = "2020-05-20";
$str =~ m/(\d{4})-(\d{2})-(\d{2})/;

printf("Year: %s Month: %s Day: %s\n", $1, $2, $3);

In a more complex regular expression/string things may move around. In this case it's better to use named captures instead of numeric captures. This can be done by using the (?<name>) syntax. This will capture that parenthesis pair in to the hash %+ with the name specified.

$str = "2020-05-20";
$str =~ m/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

printf("Year: %s Month: %s Day: %s\n", $+{year},$+{month},$+{day});

Using named captures you can easily update your regular expression if the position of elements in your string change.

Note: If you use named captures, Perl also populates the numeric equivalent.

Leave A Reply

Adjective and animal lists

For a personal project I wanted to generate AdjectiveAnimal pairs. This required me to find a list of animal names and adjectives. This was not a trivial endeavor and required me to find, clean up, and organize several lists.

Feel free to borrow my lists if you want to save yourself a headache. Using these lists I can generate pairs like: PracticalOsprey, HumorousTermite, and DiplomaticTarpon.

I also wrote a tool to generate pairs based on these two lists.

Leave A Reply