package require Tcl 8.6
package require fileutil
package require html
package require sqlite3
proc slugify text {
string trim [regsub -all {[^[:alnum:]]+} [string tolower $text] -] -
}
proc slug-compare {a b} {
if {$a eq $b} { return 0 }
return [string compare [slugify $a] [slugify $b]]
}
proc entities text {
string map {_ _} [::html::html_entities $text]
}
proc a {url {class {}}} {
format {<a\
class="%2$s"\
href="%1$s"\
rel="noopener"\
target="_blank">%1$s</a>} [entities $url] [entities $class]
}
proc main {sql-file js-file} {
sqlite3 db :memory:
db collate SLUG slug-compare
set init [fileutil::cat ${sql-file}]
db eval $init
set cats {}
db eval {
SELECT
categories.name AS category,
artists.artist,
songs.title,
songs.url,
notes.content AS note,
tag_list
FROM songs
JOIN (
SELECT DISTINCT artist
FROM songs
) AS artists
ON songs.artist = artists.artist
JOIN categories
ON categories.category_id = songs.category_id
LEFT JOIN notes
ON notes.song_id = songs.song_id
LEFT JOIN (
SELECT song_id, group_concat(tags.tag, ' ') AS tag_list
FROM tags
GROUP BY song_id
) as grouped_tags
ON grouped_tags.song_id = songs.song_id
ORDER BY
songs.category_id,
artists.artist COLLATE SLUG,
songs.title;
} row {
set class [expr {
{no-embed} in $row(tag_list) ? {} : {embed}
}]
set entry [list \
"### [entities $row(artist)] — [entities $row(title)]" \
[a $row(url) $class] \
]
if {$row(note) ne {}} { lappend entry {} $row(note) }
dict lappend cats $row(category) [join $entry \n]
}
puts "# Music links\n\nListen to some music I like.\n"
puts {## Contents}
dict for {name contents} $cats {
puts "\n\n## $name\n[join $contents \n\n]"
}
puts \n\n<script>\n[fileutil::cat ${js-file}]</script>\n
puts ---
puts {[Tags](/wiki/special:tags):\
links, list, music, recommendations.}
}
main {*}$argv