Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://anggtwu.net/blogme3/videoindex.lua.html
--   http://anggtwu.net/blogme3/videoindex.lua
--           (find-angg "blogme3/videoindex.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2021oct11


require "re"

-- Uses: (find-angg "LUA/lua50init.lua" "Re")
-- Used by: (find-TH "emacsconf2021")

VideoIndex_gram = [=[
  symbol         <- { [-A-Za-z0-9]+ }
  nbsps          <- { " " * } 
  timestr        <- ( '"' { [0-9:]+                  } '"')
  descriptionstr <- ( '"' { ( '\\' / '\"' / [^"] ) * } '"')
  sexp           <- ( '(' symbol " " nbsps timestr nbsps descriptionstr ')' )
]=]

VideoIndex = Class {
  type  = "VideoIndex",
  new   = function (T) return VideoIndex(T or {}) end,
  parse = Re({grammar = VideoIndex_gram}):c('top <- sexp'),
  __index = {
    hash = "fpsF_M55W4o",
    hashes = {
      ["2021ffll"]           = "h1CEL2fmkyc",
      ["2021orgfornonusers"] = "Eh5Wz9Vh_XM",
      ["2021workshop1"]      = "HuqJFPD871E",
      ["2021workshop2"]      = "hqqIlZBXNhk",
      ["2021workshop3"]      = "r83inf9s8zo",
      ["2021workshop4"]      = "lhpHHjBUxv8",
      ["2021workshop5"]      = "VzRsterVSXs",
      ["2021workshop6"]      = "-gi15-liGaU",
      ["2022eevmake0"]       = "Iql5C-yQk5c",
      ["2022findeevangg"]    = "FoAzpGzFCSE",
      ["2022findelispintro"] = "WowDSciGs1A",
      ["eev2019"]            = "86yiRG8YJD0",
      ["eev2020"]            = "hOAqBc42Gg8",
      ["eev2021"]            = "qM0Luz78qGw",
      ["eev2021b"]           = "QUMo7vgkHJI",
      ["eev2021pe"]          = "OW6WRnSQwc0",
      ["eev2022kla"]         = "KRobfwXd7Cw",
      ["eev2022py"]          = "QeqCYQSlz-I",
      ["eev2023repls"]       = "IDBQo_YYfA8",
      ["eev2023replsb"]      = "s3enXsuXyNg",
      ["eev2024"]            = "ZQ4mUSRcqJc",
      ["eevnav"]             = "kxBjiUo88_U",
      ["oficina20210"]       = "OW6WRnSQwc0",
      ["oficina2021a"]       = "acFPMuZ5Jf4",
      ["oficina2021b"]       = "XbuDnkfizYs",
      ["testbls"]            = "fpsF_M55W4o",
      ["2022pict2elua"]      = "hiHsUhGVLGM",
      ["2022eevwconfig"]     = "Rm29XSdGCXw",
      ["2022eevwconfigpt1"]  = "bdLbocmo3r8",
      ["2022eevwconfigpt2"]  = "ZAAxrJX-Am8",
      ["2022yttranscript"]   = "SW3Tx-lHX3o",
      ["2022tikz"]           = "d7nIzpXcV6c",
      ["2024git"]            = "lsVvokjqMY0",
      ["2024luaso"]          = "zUW-6atPvUQ",
      --
      ["cae0"]               = "XxnfW90kbZU",
      ["caev"]               = "JoAQ6TsFlto",
      ["caes"]               = "sZq2PgbLN5k",
      ["c2m211somas1d"]      = "pCD1p9FZYdI",
      ["2021saptleg"]        = "OofZQYkNVhg",
      ["calceasy"]           = "kuOxDh3egN0",
      ["c3m211cn"]           = "mrNyBAMOyqo",
      ["c3m211cn2"]          = "usBNtNyZRCA",
      ["c3cd"]               = "nxsIK0tPWAI",
      ["visaud"]             = "vVNpWTYR4wE",
      ["slogans"]            = "qwTqIBlu9CM",
      ["2024algpergs"]       = "FjhyhTxN_-o",
      ["2024lean4of0"]       = "vBkxGIrv2Q0",
      ["2024convite"]        = "wVwxugy15cU",
      ["2024lean4of0a2"]     = "MXUJ8YLp5dU",
      ["2024trywithasexp"]   = "BzovupjRhQM",
      ["2024bashtest"]       = "hok5wH4XBYg",
    },
    symboltohash = function (vli, symbol)
        local stem = symbol:match("find%-(.*)video")
        return vli.hashes[stem]
      end,
    parse = function (vli, str, sethash)
        str = str:gsub("^[^(]*", "")
        local f, s1, time, s2, descr = VideoIndex.parse(str)
        vli.f, vli.s1, vli.time, vli.s2, vli.descr = f, s1, time, s2, descr
        if vli.f and sethash then vli.hash = vli:symboltohash(f) end
        return vli
      end,
    nbsp = function (vli, s)
        return (s:gsub(" ", "&nbsp;"))
      end,
    timeurl = function (vli)
        return youtube_make_url(vli.hash, vli.time)
      end,
    timehtml = function (vli)
        return format('<a href="%s">%s<a>', vli:timeurl(), vli.time)
      end,
    descrhtml = function (vli)
        return vli.descr
      end,
    html = function (vli)
        return vli:nbsp(vli.s1)
            .. vli:timehtml()
            .. " "
            .. vli:nbsp(vli.s2)
            .. vli:descrhtml()
      end,
    videolines = function (vli, bigstr)
        local htmllines = {}
	for _,li in ipairs(splitlines(bigstr)) do
          vli:parse(li, "sethash")
          if vli.f then table.insert(htmllines, vli:html()) end
        end
        return htmllines
      end,
    videolinesconcat = function (vli, bigstr, sep)
        return table.concat(vli:videolines(bigstr), sep or "\n")
      end,
  },
}

if def then
  def [[ videolines 1Q body VideoIndex.new():videolinesconcat(body, BR()) ]]
end

--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "videoindex.lua"

bigstr = [=[
  (find-eev2021pevideo  "4:32" "1. Um pouco de contexto")
  (find-eev2021pevideo  "5:19"   "1.1.1. hackers felizes")
]=]
strs = splitlines(bigstr)
PPV(strs)

vli = VideoIndex.new():parse(strs[1], "s")
PPV(vli)
= vli:html()

vli = VideoIndex.new()
lis = vli:videolines(bigstr)

= table.concat(lis, "\n")

--]==]