Skip to content

Comment on Show HN: Supershields.io – smart, Lua-powered SVG status badgesparent

Comments

rlonnOP

Yeah, the issue is (disclaimer: I might have missed something vital here) that it is very hard to know exactly how wide text is when rendered inside the SVG. Some characters take less space than others and the safest way to determine the width of a string when it is rendered is to actually render it. This, of course, is hard to do on the server side. I'm not sure what shields.io does (I'll take a new look at it though) but given that their badges contain more predictable text strings (at least on the left-hand-side it tends to be static text) it is easier there to adjust the size of the SVG manually whe you create a new badge. Supershields badges, on the other hand, can contain very different text strings and there is no way to know what the text will be before you execute the Lua script.

Hmm, a bit rambling response, this one. I hope you get what I mean (and that I'm not completely clueless - have to look at the shields.io code again!)

I took a look. The rendering code of shields.io is here: https://github.com/badges/shields/blob/779c1ffaadfcd53ac20b5... text width is computed in preferredWidthOf, which computes the width of the text in 11px Verdana, either normal or bold: https://github.com/badges/shields/blob/779c1ffaadfcd53ac20b5... The anafanafo dependency is doing all the heavy lifting: https://www.npmjs.com/package/anafanafo

rlonnOP

Wow, thanks for that investigation. I'm pretty sure I looked at this at some point, and realized shields.io was using some esoteric NPM package that I would not find (or maybe I actually searched) the equivalent of for Golang, so I had to do something simpler.

I looked at the anafanafo package now and one of the first things they say in the presentation is "Built with Shields in mind"... So this package was custom made for shields.io, apparently. From a very quick check it seems to be a non-trivial amount of code, so not super simple to just port to Golang.

I don't want to have to start running Node and NPM packages, but would be very interested in any way to get this kind of functionality in a Go program.

I took a quick glance at anafanafo and couldn't tell if porting to Go would be easy, since the structure seems slightly convoluted. Anyway, if the lookup table approach used by anafanafo isn't easy to implement, there's always the rendering approach, using something like Cairo. Code I whipped up in a few minutes:

  package main
  
  import (
          "fmt"
  
          "github.com/gotk3/gotk3/cairo"
  )
  
  var _cr *cairo.Context
  
  func init() {
          _cr = cairo.Create(cairo.CreateImageSurface(cairo.FORMAT_RGB24, 1000, 50))
          _cr.SelectFontFace("Verdana", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
          _cr.SetFontSize(11)
  }
  
  func measureTextWidth(t string) float64 {
          return _cr.TextExtents(t).Width
  }
  
  func main() {
          measureAndPrint := func(t string) {
                  fmt.Println(t, measureTextWidth(t))
          }
          measureAndPrint("build")
          // build 24.7177734375
          measureAndPrint("passing")
          // passing 39.767578125
  }

Not sure if performance would be acceptable, though.
rlonnOP

That looks interesting. I'm installing Cairo right now - a bit of a beast though. I'll test it but might try to port the anafanafo functionality anyway. It'd be very nice to just have 100 lines of Go code and a JSON data file to deal with.

rlonnOP

Hmm, seems they just have a couple of JSON files specifying the widths of different characters in a few standard fonts. I may take a shot at porting the basic functionality to golang.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.