Scala, JSoup, HTML, CSS selectors, and a Sparkline chart

As a brief note today, here’s a little Scala application that reads an HTML file, parses it with JSoup, and then I select all of the elements with the CSS selector shown. After that, I use some Scala goodness to read all the text values of those elements, see if there is a "W" (win) or "L" (loss) character there, convert that to a Seq[Boolean], and then generated an ASCII Sparkline chart based on those results.

Note that the desired CSS selectors look like this in the HTML:

tr.Table__TR:nth-child(2) > td:nth-child(3) > span:nth-child(1)
tr.Table__TR:nth-child(4) > td:nth-child(3) > span:nth-child(1)
tr.filled:nth-child(3) > td:nth-child(3) > span:nth-child(1)
tr.filled:nth-child(9) > td:nth-child(3) > span:nth-child(1)
tr.Table__TR:nth-child(14) > td:nth-child(3) > span:nth-child(1)

And then my complete Scala source code looks like this:

//> using scala "3"
//> using lib "org.jsoup:jsoup:1.18.1"

import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import scala.jdk.CollectionConverters.*
import com.alvinalexander.utils.FileUtils.*
import com.alvinalexander.utils.PlotUtils.*

@main def CubsScoresSparkline = 

    val html = readFile("cubs-schedule.html").get

    val document: Document = Jsoup.parse(html)

    val elements = document.select("tr.Table__TR > td:nth-child(3) > span:nth-child(1)")

    val scoreResults: Seq[Boolean] = 
        elements.asScala
                .map(elem => elem.text.trim)
                .filter(s => s == "W" || s == "L")
                .map(s => if s == "W" then true else false)
                .toSeq

    println(asciiSparklineChart(scoreResults, true))

Although I say “complete,” that code does rely on all those libraries I have imported.

The resulting Sparkline graphic looks like this:

  ||||| | |  ||| || | ||||  | |  || | | |  |  | |     |   | ||   | |  |  || |    | |   || ||
--------------------------------------------------------------------------------------------
||     | | ||   |  | |    || | ||  | | | || || | ||||| ||| |  ||| | || ||  | |||| | |||  |