Last active
July 5, 2024 15:45
-
-
Save keynmol/5c277dd7cca8b6559b7a111fae772265 to your computer and use it in GitHub Desktop.
Revisions
-
keynmol revised this gist
Jul 5, 2024 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,4 +4,6 @@ This small script exists only to render a HTML page for the various yaks you are ![CleanShot 2024-07-05 at 16 37 38](https://gist.github.com/assets/1052965/f9f44e14-dac0-4939-8ca8-5b0d6ed70ca0) Copy and adapt for your needs. My [personal page](https://blog.indoorvivants.com/projects) is huge: ![image](https://gist.github.com/assets/1052965/862c8f80-7723-4fae-a893-d0a80a831644) -
keynmol created this gist
Jul 5, 2024 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,7 @@ This small script exists only to render a HTML page for the various yaks you are working on. `scala-cli run yak-render.scala -- sample-projects.yml > index.html` ![CleanShot 2024-07-05 at 16 37 38](https://gist.github.com/assets/1052965/f9f44e14-dac0-4939-8ca8-5b0d6ed70ca0) Copy and adapt for your needs. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,27 @@ categories: - name: experiments description: Code thrown together to prove something works (or doesn't) css: "bg-red-100 border-2 border-gray-300 hover:underline" - name: publications description: An application or library polished enough to be published css: "bg-sky-100 border-2 border-gray-300 hover:underline" projects: - name: Scala 3 category: publications priority: high url: "gh:scala/scala3" id: scala3 - name: Scala CLI category: experiments priority: medium url: "gh:VirtusLab/scala-cli" references: [scala3] - name: Scala CLI template category: publications priority: low url: "gh:VirtusLab/scala-cli-template" references: [scala3] This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,180 @@ //> using dep org.virtuslab::scala-yaml:0.1.0 //> using dep com.lihaoyi::scalatags::0.13.1 //> using dep com.lihaoyi::os-lib::0.10.2 //> using option -Wunused:all //> using scala "3.5.0-RC2" import org.virtuslab.yaml.* import scala.util.CommandLineParser.FromString given FromString[os.Path] with override def fromString(s: String): os.Path = os.Path(s, os.pwd) case class Defs( categories: List[Category], projects: List[Project] ) derives YamlDecoder case class Category(name: String, description: String, css: String) derives YamlDecoder case class Project( id: Option[String], name: String, category: String, priority: Priority, url: Option[YouErEl], references: Option[List[String]] ) derives YamlDecoder enum YouErEl: case Gh(coords: String) case Normal(coords: String) override def toString(): String = this match case Gh(coords) => s"https://github.com/$coords" case Normal(s) => s object YouErEl: def fromString(s: String) = s match case s"gh:$org/$repo" => YouErEl.Gh(s"$org/$repo") case s"https://$coords" => YouErEl.Normal(s) enum Priority: case High, Low, Medium given YamlDecoder[YouErEl] = YamlDecoder.forString.map(YouErEl.fromString(_)) given YamlDecoder[Priority] = summon[YamlDecoder[String]] .map(_.toLowerCase().trim) .map: case "low" => Priority.Low case "high" => Priority.High case "medium" => Priority.Medium given YamlEncoder[Priority] with def asNode(obj: Priority): Node = Node.ScalarNode(obj.toString().toLowerCase()) @main def readProjects(file: os.Path) = val decoded = os.read(file).as[Defs].fold(throw _, identity) given Resolver with val mapping = decoded.categories.map(n => n.name -> n).toMap val projectMapping = decoded.projects.flatMap(p => p.id.map(_ -> p)).toMap override def category(name: String): Category = mapping(name) override def project(id: String): Project = projectMapping(id) println(templates.layout(decoded).render) end readProjects trait Resolver: def category(name: String): Category def project(id: String): Project object templates: def layout(defs: Defs)(using Resolver) = import scalatags.Text.all.* import Priority.* def render(priority: Priority) = div( cls := "flex flex-col gap-4 shrink-0 w-4/12", defs.projects.filter(_.priority == priority).map(projectCard) ) def renderCategories() = div( cls := "grid grid-cols-2 gap-2", defs.categories.map: category => div( span( cls := s"text-md p-2 rounded-md inline-block ${category.css}", category.name ), s" ${category.description}" ) ) html( lang := "en", head( tag("title")("Projects"), script(src := "https://cdn.tailwindcss.com"), meta(charset := "UTF-8"), meta( name := "viewport", attr("content") := "width=device-width, initial-scale=1" ) ), body( div( cls := "content mx-auto w-10/12 m-8", h2("Projects", cls := "text-4xl"), h3("Agenda", cls := "text-2xl my-4"), renderCategories(), h3("Projects", cls := "text-2xl my-4"), div( cls := "flex flex-row gap-8 w-full", render(Priority.High), render(Medium), render(Low) ) ) ) ) end layout def projectCard(project: Project)(using resolver: Resolver) = import scalatags.Text.all.* val fontSize = project.priority match case Priority.High => "text-lg" case Priority.Low => "text-sm" case Priority.Medium => "text-md" val category = resolver.category(project.category) def intersperseList[A](xs: List[A], x: A): List[A] = val bld = List.newBuilder[A] val it = xs.iterator if it.hasNext then bld += it.next while it.hasNext do bld += x bld += it.next bld.result end intersperseList val references = project.references.map(value => val us = value .map(resolver.project(_)) .map: proj => proj.url match case None => span(proj.name) case Some(value) => a( href := value.toString(), proj.name, cls := "underline hover:no-underline" ) p(cls := "text-sm ml-4", "built with ", intersperseList(us, span(", "))) ) div( cls := s"$fontSize", p( cls := s"p-2 rounded-md ${category.css}", project.url match case None => b(project.name) case Some(value) => a(b(project.name), href := value.toString()) ), references ) end projectCard end templates