Archive for March, 2019

Updating my WordPress CodeHighlighterPlus to GeSHi 1.0.9.0

Thursday, March 28th, 2019

wordpress.gif

This morning I decided to see if I couldn't fix the Swift highlighting on this blog by updating to the latest GeSHi 1.0.9.0 - which is now using PHP 7, and as it turns out, so is HostMonster, so I'm in luck! 🙂 At the same time, I really wanted to document all the components and links so that this post makes it a lot easier to update things later.

As a point of reference, the CodeHighlighterPlus project is based off the CodeHighlighter WordPress plugin, and it's not bad - it's just not been updated in many years, and there are a lot of added languages in that time. Still... I tip my hat to the original authors, as I couldn't have done it without them.

The steps to do this required a little digging, but that wasn't bad - in that I had a few posts about this process already, and so let's just repeat them here to make sure it's all clear for the next time. I started by making sure that my local CodeHighlighterPlus plugin was up-to-date with the GitHub repo. All good, so let's get the latest code from GeSHi, and just overlay it on the local repo. Replace where necessary, and then we're up to date with GeSHi... but it's not really cleaned up the way I like it.

The next thing was to update the geshi.php file for a few changes. The first thing I wanted to tackle with CodeHighlighterPlus was the line numbers. There was far too much space between the lines in a code sample with line numbers. This is corrected simply in the style for the lines:

  1. /**
  2.   * Line number styles
  3.   * @var string
  4.   */
  5. protected $line_style1 = 'font-weight: normal; vertical-align:top;';
  6.  
  7. /**
  8.   * Line number styles for fancy lines
  9.   * @var string
  10.   */
  11. protected $line_style2 = 'font-weight: bold; vertical-align:top;';

to:

  1. /**
  2.   * Line number styles
  3.   * @var string
  4.   */
  5. protected $line_style1 = 'margin: 0; font-weight: normal; vertical-align:top;';
  6.  
  7. /**
  8.   * Line number styles for fancy lines
  9.   * @var string
  10.   */
  11. protected $line_style2 = 'margin: 0; font-weight: bold; vertical-align:top;';

The last change is for the blank lines that start, and end, the code section when you use line numbers. It's just plain annoying. Change:

  1. // Get code into lines
  2. /** NOTE: memorypeak #2 */
  3. $code = explode("\n", $parsed_code);
  4. $parsed_code = $this->header();

to:

  1. // Get code into lines
  2. /** NOTE: memorypeak #2 */
  3. $code = explode("\n", $parsed_code);
  4. // remove a blank first and last line
  5. if ('' == trim($code[count($code) - 1])) {
  6. unset($code[count($code) - 1]);
  7. $code = array_values($code);
  8. }
  9. if ('' == trim($code[0])) {
  10. unset($code[0]);
  11. $code = array_values($code);
  12. }
  13. $parsed_code = $this->header();

and we are good to go with the changes to the code. Check everything in, push it up to GitHub and we're ready to deploy it.

At this point, I just need to deploy this to each of the WordPress sites on my server - and that's as simple as:

  $ cd public_html/blog/wp-content/plugins/CodeHighlighterPlus
  $ git pull

where blog is the directory in the WordPress content for the specific blog I'm working with. I simply use GitHub as the mechanism of deployment - with a pull system to make sure it doesn't mess too much stuff up.

In this release of GeSHi, we now have support for the following languages:

4cs            e              magiksf        qml
6502acme       ecmascript     make           racket
6502kickass    eiffel         mapbasic       rails
6502tasm       email          mathematica    rbs
68000devpac    epc            matlab         rebol
abap           erlang         mercury        reg
actionscript   euphoria       metapost       rexx
actionscript3  ezt            mirc           robots
ada            f1             mk-61          rpmspec
aimms          falcon         mmix           rsplus
algol68        fo             modula2        ruby
apache         fortran        modula3        rust
applescript    freebasic      mpasm          sas
apt_sources    freeswitch     mxml           sass
arm            fsharp         mysql          scala
asm            gambas         nagios         scheme
asp            gdb            netrexx        scilab
asymptote      genero         newlisp        scl
autoconf       genie          nginx          sdlbasic
autohotkey     gettext        nimrod         smalltalk
autoit         glsl           nsis           smarty
avisynth       gml            oberon2        spark
awk            gnuplot        objc           sparql
bascomavr      go             objeck         sql
bash           groovy         ocaml-brief    standardml
basic4gl       gwbasic        ocaml          stonescript
batch          haskell        octave         swift
bf             haxe           oobas          systemverilog
biblatex       hicest         oorexx         tcl
bibtex         hq9plus        oracle11       tclegg
blitzbasic     html4strict    oracle8        teraterm
bnf            html5          oxygene        texgraph
boo            icon           oz             text
c              idl            parasail       thinbasic
c_loadrunner   ini            parigp         tsql
c_mac          inno           pascal         twig
c_winapi       intercal       pcre           typoscript
caddcl         io             per            unicon
cadlisp        ispfpanel      perl           upc
ceylon         j              perl6          urbi
cfdg           java           pf             uscript
cfm            java5          phix           vala
chaiscript     javascript     php-brief      vb
chapel         jcl            php            vbnet
cil            jquery         pic16          vbscript
clojure        julia          pike           vedit
cmake          julia.bak      pixelbender    verilog
cobol          kixtart        pli            vhdl
coffeescript   klonec         plsql          vim
cpp-qt         klonecpp       postgresql     visualfoxpro
cpp-winapi     kotlin         postscript     visualprolog
cpp            latex          povray         whitespace
csharp         lb             powerbuilder   whois
css            ldif           powershell     winbatch
cuesheet       lisp           proftpd        xbasic
d              llvm           progress       xml
dart           locobasic      prolog         xojo
dcl            logtalk        properties     xorg_conf
dcpu16         lolcode        providex       xpp
dcs            lotusformulas  purebasic      xyscript
delphi         lotusscript    pycon          yaml
diff           lscript        pys60          z80
div            lsl2           python         zxbasic
dos            lua            q
dot            m68k           qbasic

And with the addition of Swift, I have highlighting on all the code snippets I've been adding. Very nice!

The Dreadful State of IM Clients

Thursday, March 28th, 2019

Adium.jpg

Yesterday morning I noticed that ICQ wasn't connecting within Adium - it was failing to connect with the error:

Error: Unable to connect to BOS server: Connection refused

and nothing I could find was changing that error. Now, to be fair, I can't ever remember using ICQ for chatting with anyone, but when I got Adium all those years ago, I made sure to get accounts on all the supported platforms so that I could be available to anyone wanting to chat.

Sadly, one by one, they have fallen off... or shut down... or locked down the services to only allow proprietary client access. I guess I get it, I'm just seeing the monitization of all these chat clients - HipChat, then Slack and Google Hangouts... and those are the ones that are still alive. Hotmail went to Microsoft, and then they shut it down. AOL - gone. Yahoo! - gone.

I now have Adium that hasn't really been updated in about a year, and it's got one client: Gtalk. And we know that this is getting shut down soon by Google to force us all to use their Hangouts client. I guess it's just the pendulum swinging back to the "Give me my money!" - but for folks like Microsoft and Google - do they really need the money they'd get off me using Skype or Hangouts?

The truth is that I won't use either - except for work, and there I have to so it's a captive audience. But what they've really done is pushed me to use my phone. I can text all these folks, and make group texts, and I can use any phone I want.

It's just so very sad.

UPDATE: yup... I did a little searching on the net to see what's up, and it turns out the owners of ICQ have decided that 28-Dec-2018 was the cut-off date for the old protocol that was supported in libpurple - which is used by Adium. Just another case of trying to monetize the IM space. In this case, I'm OK with letting this one go. Not worth the tracking risks for ICQ.

On Object Oriented Designs and Complexity

Tuesday, March 26th, 2019

Code Monkeys

Today, with the update of Xcode 10.2, and Swift 5.0, I had to struggle with the formatting of strings in order to find the pattern they represented. The point is really this: Represent the pattern of the characters in a word so that 'bee' and 'too' and 'see' all look like the same pattern.. This is used in my CryptoQuip solver, and the point is to group words by their patterns because we don't know what the actual characters are, but we do know their patterns - because it's a simple substitution cypher.

So how to do that? Well... when we look at Clojure - which just deals with the string as a sequence of characters - just data, we have:

(defn pattern
  "Function to take a word (as a string) and return a vector that is the
  pattern of that word where the values are the index of the character.
 
    => (pattern \"see\")
      (0 1 1)
    => (pattern \"rabbit\")
      (0 1 2 2 4 5)
  "
  [word]
  (map #(.indexOf word (int %)) word))

and if, for the sake of this post, we drop the comments, we get something very simple:

(defn pattern
  [word]
  (map #(.indexOf word (int %)) word))

if we look at this in Swift, we see:

  extension String {
    /**
     Attributes of a string that return a string that is the pattern of that
     word where the values are the index of the character. This is a simple
     baseline pattern generator for the words so they are comparable.
 
    ```
        => "see".pattern
        "abb"
        => "rabbit".pattern
        "abccef"
    ```
     */
    var pattern: String {
      get {
        let ascii: [Character] = ["a","b","c","d","e","f","g","h","i","j","k",
                                  "l","m","n","o","p","q","r","s","t","u","v",
                                  "w","x","y","z"]
        var ans = ""
        let src = Array(self.utf8)
        for c in src {
          ans.append(ascii[src.firstIndex(of: c)!])
        }
        return ans
      }
    }
  }

And the reason to use a String as opposed to a sequence of numbers in Swift, is that those comparisons are not nearly as nice in Swift as simple String comparisons are. But I look at all this, and while the protocols in Swift are nice - to add methods to existing classes - it's much the same in Ruby, and it can lead to some very tough bugs - and so you have to be very careful using them.

And this got me to thinking about the complexity of most systems and the OOA&D systems I've seen in C++, Java, Ruby, ObjC, Swift - and it really is hard to come up with a really great design if you don't put in a ton of effort on the work. Sure... Boost for C++, and Java classes, are good designs - but they had a lot of backing and time to get right. ObjC - specifically Foundation, is well-done, but again, that was a serious investment by NeXT. But most of the non-OS-level projects... like those in the wild, they are a mess.

I don't think this is an accident. I think good, solid, OOA&D is hard because there are so many times when a method isn't clearly belonging to one object, or another - and the language might not be set up to have stand-alone functions as an alternative - Java, Scala. So they have to go somewhere, and that means that things get tossed into the closest reasonable object - as long as it's "close enough". But then 6 months later, it's a disaster. No one remembers why each method is on these objects... and the circular references require interfaces, and then implementations of those interfaces... and it just gets to be a mess.

What I believe is that the simpler the code, the better. This means more abstract. More critical thinking, and less "let's just hammer this out" work. I'm sure there are folks that can do a good job on an OOA&D project - and it could be massive and complex... but those people are rare - very rare. And in general, you end up with really bad objects that create horrible inclusion requirements, and even worse threading issues - because it all mutable, and you just have systems that can't get larger than a certain size.

That's not good. Math doesn't work that way. Neither should coding.

Xcode 10.2 is Out

Tuesday, March 26th, 2019

xcode.jpg

This morning, after I updated to macOS 10.14.4, I noticed that Xcode 10.2 was out with Swift 5, and that has the new Strings, and the ABI compatibility, and a host of new things. So let's get that going, and see how it changes things. I really haven't read what is new in Swift 5 - other than the new Strings, so that will be something to read up on this morning.

What I've found in converting an ObjC project is that a few of the localizations needed to be cleaned up - Xcode did that just fine, and then it built and ran just fine. But for the Swift project, it complained about the use of index(of:) and suggested that it be changed to firstIndex(of:) - which is fine, but I don't know that anyone used to coding for very long makes that mistake - but OK... I get it.

The next one said that in this code:

  ans.append(ascii[self.index(of: c)!.encodedOffset])

needed to be changed to:

  ans.append(ascii[self.firstIndex(of: c)!.utf16Offset(in: self)])

and figuring that out took some time.

Specifically, they deprecated the encodedOffset - which they say was being misused. And then didn't really give me a replacement. I had to fiddle and search the docs for what to put in it's place. And given that this is coming off a call to self - how is it that utf16Offset() doesn't default to that?

In any case, I got that fixed, and then I refactored the code for pattern from:

  let ascii: [Character] = ["a","b","c","d","e","f","g","h","i","j","k",
                            "l","m","n","o","p","q","r","s","t","u","v",
                            "w","x","y","z"]
  var ans = ""
  for c in self {
    ans.append(ascii[self.firstIndex(of: c)!.utf16Offset(in: self)])
  }
  return ans

to:

  let ascii: [Character] = ["a","b","c","d","e","f","g","h","i","j","k",
                            "l","m","n","o","p","q","r","s","t","u","v",
                            "w","x","y","z"]
  var ans = ""
  let src = Array(self.utf8)
  for c in src {
    ans.append(ascii[src.firstIndex(of: c)!])
  }
  return ans

I just didn't like the way the encoding was being handled, and that got to be a real annoyance... so by just converting it to UTF8, and then using that array for indexing, I was able to do the same thing - and it looks a lot cleaner.

I'm less and less a fan of the speed with which they released Swift. I understand they needed to get it out in the wild, and they had to answer requests for features, but they added too many too quickly, and without the long-term consideration that they are usually known for. I mean look at ObjC... the classes changed a little, but the language was shipping product for 5 yrs, and Swift has been around for 5 yrs, and it's still not close to stable.

Part of it is also that they stuck with OOA&D, and that's got to be a killer.

Apple News+ is Pretty Nice

Tuesday, March 26th, 2019

Apple Computers

This morning I signed up for Apple News+ - and I have to say, it's pretty nice. Sure, it's having some growing pains this morning - the News app in iOS 12.2 is crashing a bit when it can't talk to the servers at Apple HQ, but that will get worked out. For the little time it was stable this morning, I was really impressed with the offerings - some things I have paid for in the past, but just haven't kept up with, and others I've always wanted to have available to read:

  • Scientific American
  • Time
  • Runner's World
  • The Wall Street Journal
  • Bloomberg Businessweek
  • The New Yorker
  • The Atlantic
  • Flying

it's a list that keeps going, and it's really impressive. Sure, it's more than $30/yr - but that's for one magazine, and I can carry these all with me in my pocket on my phone. It's really just amazing.

Now, I've been reading a lot more on the News app because I just can't stand Facebook any more, and this is a lot better place to get news - it's a known source, and that's something I find I don't like about all the stuff you find on Facebook - you just can't trust it.

I'm not sure about the other services they introduced yesterday - except the Apple Card. That's something I'll get because of the Daily Cash Back that I can use because I put so much of my life on my Quicksilver card with 1.5% cash back. This is just a better deal.

Can't wait for the Summer when they get that going...

iTerm2 3.3.0beta1 new Title Bar

Monday, March 25th, 2019

iTerm2

This morning I saw that iTerm2 had a new release - 3.3.0beta1, and in this new release, there were several new options for the Title Bar, and even a fancy Status Bar for things like the git branch, running app, etc. It is quite a nice visual upgrade. So this is how I've enabled the new Title Bar.

First, set the iTerm2 Theme to Minimal. Go to Settings, select the Appearance tab, and choose "Minimal" from the Theme dropdown.

Next, select the Profiles tab, select Window, and in the dropdown for Settings for New Window, select Compact.

Go to Advanced, and scroll down to the Tab settings, and for Tab bar height for compact windows with minimal theme, I have 22. It's about the exact size of the old window title bar, and it looks just great:

ITerm2 Title Bar

Happy Pi Day!

Thursday, March 14th, 2019

pi.jpg

This was a day that the kids would always look forward to when they were in elementary school. The teachers at their school would always make a fun day of "Pi Day". Today, it makes me feel like going to Baker's Square and having a piece, but that's just a fleeting emotion... I'll be just fine with the memories of the days the kids would come back from school and tell me all about their "Pi Day".

Some memories are just so good, they survive the bad.

Sublime Text 3.2 is Out

Wednesday, March 13th, 2019

Sublime Text 2

This morning I saw a tweet from @SublimeHQ saying that Sublime Text 3.2 was out, and the list of fixes and features was really quite nice. The git integration is very nice - you can now see the branch you're on in the status bar, and when you click that, it will bring up Sublime Merge. It's not bad... not sure how much I'll use that, but it's nice that they have it integrated, and can show the branch on the editor window.

They also added a lot of nice Mac features:

  • Mac: Added Mojave support
  • Mac: Add full support for macOS native tabs
  • Mac: Ensure context menus are shown without scrolling
  • Mac: Error message dialogs can now be closed with the escape key
  • Mac: Improved window placement
  • Mac: Improved resize performance

I wasn't really disappointed with the performance, but to see the support for native tabs and Mojave - it's just really nice.

They also updated the syntax highlighting for Clojure, D, Go, and Lua - and while I'm not a big fan of the others, the changes they made to Clojure really nice. I also noticed that they have done something with the rendering in the Clojure files - could all be part of the syntax highlighting, but I'll have to see what it turns out to be. Looks like they "thinned out" the strokes on the comments, but we'll see. In any case, it's a lot nicer now for most of the coding I do.

It's an exciting upgrade, and it makes my day a little brighter.

The Landscape is Changing

Monday, March 11th, 2019

cubeLifeView.gif

This morning I read a tweet that was re-tweeted by a guy I used to work with. The tweet said:

If anyone needed to hear it: I don't care about .dev domains or mechanical keyboards, I don't read Hacker News, I don't have a customized terminal, I don't spend all weekend coding, I sometimes use the Git GUI in my IDE, and I am valid in tech and so are you.

The person that wrote this isn't important - they are right - they are every bit as valid in this industry as anyone else. There isn't a "test" of "worthiness" to get, and keep, a job in this industry. And those that treat someone as less of a person, or less of a value to the organization are just missing the point. Badly.

Not everyone has to want to do these things. That's perfectly fine. Take another industry - doctors, lawyers, professional sports - there are all kinds of doctors that don't read up on the medical journals in their weekends... and plenty of lawyers that don't read briefs to stay up on things... and all kinds of different levels of pro sports.

But we can't then also insist that the very best surgeon work on our loved ones. Or that if we're in trouble, and need a lawyer, that you get the very best one you can get to get out of trouble. Right? And we certainly can't be disappointed in our favorite team for not winning - Right? They are just as valid as anyone else in that industry. Right?

Or is 'valid' the only metric we want to use here? I agree that the old Doc Hollywood story is about what you value - and sure, you're not doing amazing surgery saving lives, but that's not what you value - relationships are. But no one would call a Doc Hollywood to do heart surgery - and when you need a heart surgeon, you don't want to think that Doc Hollywood is your best alternative.

And when you feel you've been wrongly accused - you probably don't want to have to rely on the Public Defender. They are just as valid in the legal profession... and no one should make them feel like "less" of a lawyer because they are in the Public Defender's office... right?

As I read this tweet two things struck me:

  • This person works with some serious jerks - it's clear that this person has been working with, or working around, some major jerks that feel there is some litmus test to be a "good developer" - or even a "real developer". That's just wrong, and you can't change other people's attitudes, so my advice would be to find another job. There are better ones out there.
  • 'Valid' isn't the same thing as 'Value' - no one should be so marginalized that they feel that their fundamental worth is in question - but that's not to say that everyone is equal, either. Skills matter. Experience matters. Value isn't the same thing as validity. I can play basketball... but I have no business playing on the Lakers. And I shouldn't expect to.

I would like to tell this person: "Listen, you're right - you work with jerks - ignore them. Get a job that you like, and do your best." but at the same time, I can't say that this person should also expect to see the same paycheck as those that work 7 days a week. Or those that have devoted decades to their craft. Just recognize that choices matter.

Technology really has become the new workplace where classic blue-collar and white-collar jobs are mixed into the same pot. There's nothing wrong with picking what you want to do, and what's important to you - and you should not be made to feel your choices somehow make you less of a person. But they do have consequences.

An Old Knight – in a Rusted Suit of Armor

Wednesday, March 6th, 2019

Sad State of Affairs

This morning I was chatting with my Boss, and we were talking about the progress that was being made - and I had to admit, that we are starting to at least work together - as opposed to hold meetings where we disagree, but make no decisions, and just table the discussion for the next meeting. This works to simply make no progress, and it can be quite effective. But we're not there, and that's a really solid move in the right direction.

But that is not to say that yesterday wasn't a challenge. I understand how oppressive a job can be where you are not valued, where you are not listened to - I've worked in them. But the flip-side is no better - where every person in the company feels entitled to reject an assignment because they are self-empowered, and the management team does nothing to dissuade them of that opinion.

So I find myself in the position of, once again, patiently explaining requirements for a project to members of a team that simply will not accept it, and so won't be on the implementation team, and we'll simply have to get new folks. These guys can support the legacy stuff - it's all their stuff, and it'll be around for at least a year or so, so they have jobs, and comfortable ones, but they won't be on the new stuff - because they don't believe in it.

And that got me to make the statement:

I feel like an Old Knight - in a Rusted Suit of Armor. Way past his time.

and it struck me that this was a turning point for me. To see that Honor, Integrity, and Commitment are so vital to me, and so completely foreign to them. For example, I may not like what I'm doing, but it's the Job. It's the social contract on employment - I agree to do the job they ask me, and they agree to pay me the promised wage.

That's it.

No arguments.

My choice, and my power is to change jobs. That's perfectly acceptable. I can change jobs as often as I want, and for whatever reasons I wish. That's my choice and power. But if I'm here, and taking the wage, then by golly, if they ask you to do the job then you do it. Period.

This isn't about being hired as a Data Scientist, and being asked to pick up an AK-47 and defend the CEO's mansion from zombies... this is about accepting a job to develop software, and being asked do just that. It's simple.

But clearly, in today's environment, it isn't. Which is why I feel so completely out of time with many of my co-workers. They can't understand me because they don't have the same sense of what's important to me, and while I can understand why they feel entitled (too many Participation Trophies) it doesn't excuse the behavior.

Just like an Old Knight... in a rusted suit of armor.