Artifact 053d0ff993c65a962b54890e38b353499cfe039c00f2e6fbef51b98b9b0c824b:


#! /usr/bin/env tclsh
# Copyright (c) 2020 D. Bohdan.
# License: MIT.

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