big changes: themed up, sorted up, some fixes and libs

This commit is contained in:
2025-10-06 17:15:47 +02:00
parent 7afe0d8f34
commit dc45f26299
18 changed files with 997 additions and 740 deletions

View File

@@ -10,8 +10,10 @@ tmpdir=$(mktemp -d)
echo "🥚 ${GREEN}Internalize sourced files${OFF}" echo "🥚 ${GREEN}Internalize sourced files${OFF}"
sed -E 's|\. "([^$].+)"$|cat src/\1|e' "$SRC" >"$tmpdir/1.sh" sed -E 's|\. "([^$].+)"$|cat src/\1|e' "$SRC" >"$tmpdir/1.sh"
echo "🐔 ${GREEN}Internalize awk scripts${OFF}" echo "🐔 ${GREEN}Internalize awk scripts${OFF}"
sed -E 's|@@include (.+)$|cat src/\1|e' "$tmpdir/1.sh" >"$NAME" sed -E 's|@@include (.+)$|cat src/\1|e' "$tmpdir/1.sh" >"$tmpdir/2.sh"
echo "🥚 ${GREEN}Make executable and cleanup${OFF}" echo "🥚 ${GREEN}Internalize awk libraries${OFF}"
sed -E 's|@include "(.+)"$|cat src/\1|e' "$tmpdir/2.sh" >"$NAME"
echo "🐔 ${GREEN}Make executable and cleanup${OFF}"
chmod +x "$NAME" chmod +x "$NAME"
rm -rf "$tmpdir" rm -rf "$tmpdir"
echo "🍳 ${GREEN}Done:${OFF} Sucessfully built ${BOLD}${GREEN}$NAME${OFF}" echo "🍳 ${GREEN}Done:${OFF} Sucessfully built ${BOLD}${GREEN}$NAME${OFF}"

View File

@@ -1,47 +1,63 @@
# List artists # List artists
# #
# parameter file_local_artists: This is an optional parameter with the path # parameters:
# to a file with a MusicBrainz artist ID per # flagfile: path to a file with a MusicBrainz artist ID per line (optional)
# line. # sortby: sort selector (see `src/sh/awk.sh`)
# parameter format_person: This is the format string for single person #
# artists, which includes the <<name>> # theme parameters (see `src/sh/awk.sh` and `src/sh/theme.sh`)
# placeholder. # format Format string
# parameter format_disambiguation: This is the format string for the # flag_local Flag for locally available music
# disambiguation part of the artist, with a # flag_nolocal Flag for locally unavailable music
# placeholder <<disambiguation>>. # type_person Single-person artist indicator
# parameter format_group: This is as format_person, but for music # type_group Artist group indicator
# groups. # fmtname `printf` expression to transform artist names
# parameter format_local: String to indicate that there is some music # fmtdisambiguation `printf` expression to transform disambiguation
# locally available of an artist
# #
# This awk program takes as input a sequence of lines where the first item is # This awk program takes as input a sequence of lines where the first item is
# the MusicBrainz artist ID, the second item is the type of the artist # the MusicBrainz artist ID, the second item is the type of the artist
# ("Person" or "Group"), the third item is the name, and the forth item is a # ("Person" or "Group"), the third item is the name, the forth item is the sort
# disambiguation string. # string, and the fifth item is a disambiguation string.
# #
# The output of this script is a sequence of tab-delimited lines where the # The output of this script is a sequence of tab-delimited lines. The first
# first item is the format_local string, if some music of that artist is # `AV_FMT_CNT` lines are those that will be displayed to the user. The following lines are
# locally accessible, and the empty string otherwise, the second item is the # - Field intended for sorting
# formatted artist string (formatted according to format_person or # - constant 0 (field intended for parent id)
# format_group), the third item is the constant string "0" indicating the # - MusicBrainz artist ID
# parent MusicBrainz ID, and the last item is the MusicBrainz artist ID. # - 1 if some music of that artist is locally available
@include "lib/awk/lib.awk"
BEGIN { BEGIN {
OFS="\t" OFS="\t"
local_artists[0] = 0 flagged[0] = 0
delete local_artists[0] delete flagged[0]
if (file_local_artists) { if (flagfile) {
while ((getline < file_local_artists) == 1) while ((getline < flagfile) == 1)
local_artists[$1] = 1 flagged[$1] = 1
close(file_local_artists) close(flagfile)
} }
} }
{ {
gsub("&", "\\\\&") # Read data
name = $2 == "Group" ? format_group : format_person line = format
l = local_artists[$1] ? format_local : "" mbid = $1
if ($4) type = $2
name = name " " format_disambiguation name = $3 ? sprintf(fmtname, escape($3)) : ""
sub("<<disambiguation>>", $4, name) sort = 0
sub("<<name>>", $3, name) if (sortby) {
print l, name, "0", $1 sort = sortby == "sort-artist-sortname" ? $4 : $3
}
disa = $5 ? sprintf(fmtdisambiguation, escape($5)) : ""
# Transform data and fill placeholders
if (flagged[mbid])
gsub("<<flag>>", flag_local, line)
else
gsub("<<flag>>", flag_nolocal, line)
if (type == "Group")
gsub("<<type>>", type_group, line)
else
gsub("<<type>>", type_person, line)
gsub("<<name>>", name, line)
gsub("<<disambiguation>>", disa, line)
print line, sort, "0", mbid, flagged[mbid]
} }

View File

@@ -1,62 +1,62 @@
# List recordings # List release groups
# #
# parameter file_local_recordings: This is an optional parameter with the path # flagfile Path to a file with a MusicBrainz track ID per line, tab-delimited
# to a file with a MusicBrainz recording ID # from the path to the decoration file (optional)
# per line. #
# parameter format: The format of a recording line including the # theme parameters (see `src/sh/awk.sh` and `src/sh/theme.sh`)
# placeholders <<med>> for medium number, # format Format string
# <<nr> for for track number within a medium, # flag_local Flag for locally available music
# <<title>> for the title, <<artist>> for the # flag_nolocal Flag for locally unavailable music
# artist string, and <<duration>> for the # playing_yes Mark for currently playing track
# track duration. # playing_no Mark for currently not playing track
# parameter format_local: String to indicate that the track is locally # fmtmedia `printf` expression for media identifier
# available # fmtnr `printf` expression for track number
# parameter format_current: String to indicate that the track is # fmttitle `printf` expression for title
# "currently playing" # fmtartist `printf` expression for artist
# parameter current_id: MusicBrainz track ID of a track to be marked # fmtduration `printf` expression track duration
# as "currently playing"
# #
# The input to this awk program is a sequence of lines containing the following fields: # The input to this awk program is a sequence of lines containing the following fields:
# Field 1: The MusicBrainz ID of the release this track belongs to # Field 1: The MusicBrainz ID of the release this track belongs to
# Field 2: MusicBrainz ID of this track # Field 2: MusicBrainz ID of this track
# Field 3: Number of media of theis release # Field 3: Number of media of this release
# Field 4: Medium number of this track within the release # Field 4: Medium number of this track within the release
# Field 5: Track number of this track within the medium # Field 5: Track number of this track within the medium
# Field 6: Duration of this track in miliseconds # Field 6: Duration of this track in milliseconds
# Field 7: Title of this track # Field 7: Title of this track
# Field 8: Artist of this track # Field 8: Artist of this track
# Field 9: Path to decoratoin file of this release # Field 9: Path to decoration file of this release
# Field 10: Empty outside of playlists, else "yes" if the track is currently
# being played, and something else otherwise.
# #
# The output is a sequence of tab-delimited lines containing the following fields: # The output of this script is a sequence of tab-delimited lines. The first
# Field 1: Sort value (to sort the track within the release) # `REC_FMT_CNT` fields are those that will be displayed to the user. The
# Field 2: The string `format_local` if the track is locally available # following fields are
# Field 3: The string `format_current` if the track has MusicBrainz ID `current_id` # - Constant 0 (we will not sort)
# Field 4: The track line to be displayed according to `format` # - MusicBrainz release ID if specified, else the constant "0"
# Field 5: The MusicBrainz ID of the release this track belongs to # - MusicBrainz track ID
# Field 6: The MusicBrainz ID of this track ":" separated from the path to the # - Path to decoration file if some music of that release is locally available
# decoration file of this release
@include "lib/awk/lib.awk"
BEGIN { BEGIN {
OFS="\t" OFS="\t"
local_recordings[0] = 0 flagged[0] = 0
delete local_recordings[0] delete flagged[0]
if (file_local_recordings) { if (flagfile) {
while ((getline < file_local_recordings) == 1) while ((getline < flagfile) == 1)
local_recordings[$1] = 1 flagged[$1] = 1
close(file_local_recordings) close(flagfile)
} }
} }
{ {
parentid = $1 # Read data
id = $2 line = format
medtot = $3 releaseid = $1
med = $4 mbid = $2
nr = $5 medtot = $3 + 0
med = ($4 && medtot >= 2) ? sprintf(fmtmedia, escape($4)) : ""
nr = $5 ? sprintf(fmtnr, escape($5)) : ""
dur = $6 dur = $6
title = $7
artist = $8
deco = local_recordings[id] ? $9 : ""
gsub("&", "\\\\&", title)
gsub("&", "\\\\&", artist)
# Parse duration # Parse duration
if (dur) { if (dur) {
dur = int(dur / 1000) dur = int(dur / 1000)
@@ -70,17 +70,27 @@ BEGIN {
} else { } else {
dur = "??:??" dur = "??:??"
} }
line = format dur = sprintf(fmtduration, dur)
if (medtot == 1) title = $7 ? sprintf(fmttitle, escape($7)) : ""
sub("<<med>>", "", line) artist = $8 ? sprintf(fmtartist, escape($8)) : ""
if (flagged[mbid] && $9)
flagged[mbid] = $9
current = $10
# Transform data and fill placeholders
if (flagged[mbid])
gsub("<<flag>>", flag_local, line)
else else
sub("<<med>>", med, line) gsub("<<flag>>", flag_nolocal, line)
sub("<<nr>>", nr, line) gsub("<<media>>", med, line)
sub("<<title>>", title, line) gsub("<<nr>>", nr, line)
sub("<<artist>>", artist, line) gsub("<<title>>", title, line)
sub("<<duration>>", dur, line) gsub("<<artist>>", artist, line)
l = local_recordings[id] ? format_local : "" gsub("<<duration>>", dur, line)
c = id == current_id ? format_current : "" if (current) {
sortk = med" "nr if (current == "yes")
print sortk, l, c, line, parentid, id ":" deco gsub("<<playing>>", playing_yes, line)
else
gsub("<<playing>>", playing_no, line)
}
print line, "0", releaseid ? releaseid : "0", mbid, flagged[mbid] ? flagged[mbid] : (current ? $9 : "")
} }

View File

@@ -1,48 +1,37 @@
# List release groups # List release groups
# #
# parameter file_local_releasegroups: This is an optional parameter with the # flagfile path to a file with a MusicBrainz release-group ID per line (optional)
# path to a file with a MusicBrainz # sortby sort selector (see `src/sh/awk.sh`)
# release-group ID per line. # origartist Artist name to compare release-groups (optional)
# parameter format_release: Format for the release title with a # artistid MusicBrainz ID of the artist (optional)
# <<title>> placeholder. #
# parameter format_release_w_artist: Same as `format_release` but with an # theme parameters (see `src/sh/awk.sh` and `src/sh/theme.sh`)
# additional <<artist>> placeholder. # format Format string
# parameter format_year: Format string for the year part, with a # flag_local Flag for locally available music
# <<year>> placeholder. # flag_nolocal Flag for locally unavailable music
# parameter format_local: String to indicate that the track is # type_single Single
# locally available. # type_album LP
# parameter artist: Artist name to compare release-groups # type_ep EP
# artist names against. If the names # type_broadcast Broadcast
# differ, then the format with <<artist>> # type_other Other type
# placeholder is used (optional) # type_unknown Type unknown
# parameter artistid MusicBrainz ID of the artist (optional). # hassecondary_yes Release group has secondary type(s)
# Then, there are several format strings that indicate the type of a release # hassecondary_no Release group does not have any secondary type
# group. The types are implicit from the parameter names: # fmtsecondary `printf` expression to display secondary type
# parameter format_album # secondary_soundtrack ...
# parameter format_single # secondary_spokenword ...
# parameter format_ep # secondary_interview ...
# parameter format_broadcast # secondary_audiobook ...
# parameter format_other # secondary_audiodrama ...
# Some release groups have also a secondary type. The presence of a secondary # secondary_live ...
# type is formatted using # secondary_remix ...
# parameter format_secondary. # secondary_djmix ...
# The list of all secondary types (implicit from their variable names) are # secondary_mixtape ...
# formatted using # secondary_demo ...
# parameter format_secondary. # secondary_fieldrec ...
# Each of the secondary types is specified with (the type is implicit from the # fmttitle `printf` expression to transform title
# variable names) # fmtartist `printf` expression to transform artist
# parameter format_compilation # fmtyear `printf` expression to transform year
# parameter format_soundtrack
# parameter format_spokenword
# parameter format_interview
# parameter format_audiobook
# parameter format_audiodrama
# parameter format_live
# parameter format_remix
# parameter format_djmix
# parameter format_mixtape
# parameter format_demo
# parameter format_fieldrec
# #
# The input to this awk program is a sequence of lines containing the following # The input to this awk program is a sequence of lines containing the following
# fields: # fields:
@@ -53,76 +42,83 @@
# Field 5: Title of the release group # Field 5: Title of the release group
# Field 6: The artist as credited # Field 6: The artist as credited
# #
# The output is a sequence of tab-delimited lines with the fields: # The output of this script is a sequence of tab-delimited lines. The first
# Field 1: Sort value to sort release groups # `RGV_FMT_CNT` fields are those that will be displayed to the user. The
# Field 2: The flag `format_local` if the release group is accessible locally, # following fields are
# and "" else. # - sort key (release year)
# Field 3: Release-group type # - MusicBrainz artist ID if specified, else the constant "0"
# Field 4: Release-group string # - MusicBrainz release-group ID
# Field 5: Release-group year # - 1 if some music of that release group is locally available
# Field 6: Secondary types
# Field 7: MusicBrainz artist ID of the release group artist, if there is one, @include "lib/awk/lib.awk"
# else "0"
# Field 8: MusicBrainz release-group ID
BEGIN { BEGIN {
OFS="\t" OFS="\t"
local_releasegroups[0] = 0 flagged[0] = 0
delete local_releasegroups[0] delete flagged[0]
if (file_local_releasegroups) { if (flagfile) {
while ((getline < file_local_releasegroups) == 1) while ((getline < flagfile) == 1)
local_releasegroups[$1] = 1 flagged[$1] = 1
close(file_local_releasegroups) close(flagfile)
} }
} }
{ {
line_type = "" # Read data
line_sectype = "" line = format
line_year = "" mbid = $1
gsub("&", "\\\\&")
id = $1
type = $2 type = $2
sectype = $3 sectype = $3
year = substr($4, 1, 4) + 0 year = $4 ? sprintf(fmtyear, substr($4, 1, 4) + 0) : ""
title = $5 title = $5 ? sprintf(fmttitle, escape($5)) : ""
artistcredit = $6 artist = escape($6) != origartist ? sprintf(fmtartist, escape($6)) : ""
line_release = artist == artistcredit ? format_release : format_release_w_artist sort = $4 ? -$4 : 0
l = local_releasegroups[$1] ? format_local : "" sort = 0
switch (type) { if (sortby) {
case "Single": line_type=format_single; break sort = sortby == "sort-rg-year" ? ($4 ? -$4 : 0) : $5
case "Album": line_type=format_album; break
case "EP": line_type=format_ep; break
case "Broadcast": line_type=format_broadcast; break
case "Other": line_type=format_other; break
default: line_type=""
} }
# Transform data and fill placeholders
if (flagged[mbid])
gsub("<<flag>>", flag_local, line)
else
gsub("<<flag>>", flag_nolocal, line)
switch (type) {
case "Single": t = type_single; break
case "Album": t = type_album; break
case "EP": t = type_ep; break;
case "Broadcast": t = type_broadcast; break
case "Other": t = type_other; break
default: t = type_unknown; break
}
gsub("<<type>>", t, line)
if (sectype)
gsub("<<hassecondary>>", hassecondary_yes, line)
else
gsub("<<hassecondary>>", hassecondary_no, line)
gsub("<<title>>", title, line)
gsub("<<artist>>", artist, line)
gsub("<<year>>", year, line)
t = ""
s = ""
split(sectype, a, ";") split(sectype, a, ";")
for (i in a) { for (i in a) {
t=""
switch (a[i]) { switch (a[i]) {
case "Compilation": t=format_compilation; break case "Compilation": t = secondary_compilation; break
case "Soundtrack": t=format_soundtrack; break case "Soundtrack": t = secondary_soundtrack; break
case "Spokenword": t=format_spokenword; break case "Spokenword": t = secondary_spokenword; break
case "Interview": t=format_interview; break case "Interview": t = secondary_interview; break
case "Audiobook": t=format_audiobook; break case "Audiobook": t = secondary_audiobook; break
case "Audio drama": t=format_audiodrama; break case "Audio drama": t = secondary_audiodrama; break
case "Live": t=format_live; break case "Live": t = secondary_live; break
case "Remix": t=format_remix; break case "Remix": t = secondary_remix; break
case "DJ-mix": t=format_djmix; break case "DJ-mix": t = secondary_djmix; break
case "Mixtape/Street": t=format_mixtape; break case "Mixtape/Street": t = secondary_mixtape; break
case "Demo": t=format_demo; break case "Demo": t = secondary_demo; break
case "Field recording": t=fieldrec; break case "Field recording": t = secondary_fieldrec; break
} }
if (t) if (t)
line_sectype=line_sectype ? line_sectype ", " t : t s = s ? s ", " t : t
} }
if (sectype) { s = s ? sprintf(fmtsecondary, s) : ""
line_type = sprintf(format_has_secondary, line_type) gsub("<<secondary>>", s, line)
line_sectype = sprintf(format_secondary, line_sectype) print line, sort, artistid ? artistid : "0", mbid, flagged[mbid]
}
sub("<<title>>", title, line_release)
sub("<<artist>>", artistcredit, line_release)
line_year = year ? format_year : ""
sub("<<year>>", year, line_year)
sortk = year ? year : 0
print sortk, l, line_type, line_release, line_year, line_sectype, artistid ? artistid : "0", id
} }

View File

@@ -1,35 +1,31 @@
# List releases # List release groups
# #
# parameter file_local_releases: This is an optional parameter with the # flagfile path to a file with a MusicBrainz release ID per line,
# path to a file with a MusicBrainz # tab-delimited from the path to the decoration file
# release ID per line. # (optional)
# parameter format_release: Format for the release with the # origtitle Title of release group (optional)
# placeholders <<status>>, <<tracks>>, # origartist Artist credit of release group (optional)
# <<media>>, <<year>>, <<country>>, and # releasegroupid MusicBrainz release-group ID (optional)
# <<label>>. #
# parameter format_release_title_artist: Format to specify title and artist, # theme parameters (see `src/sh/awk.sh` and `src/sh/theme.sh`)
# with the placeholders <<title>> and # format Format string
# <<artist>>. # flag_local Flag for locally available music
# parameter format_release_title: Format to specify the release title # flag_nolocal Flag for locally unavailable music
# with a placeholder <<title>>. # status_official Official release
# parameter format_release_artist: Format to specify the release artist # status_promo Promotional release
# with a placeholder <<artist>>. # status_bootleg Bootleg release
# parameter format_local: String to indicate that the track is # status_pseudo Pseudo release
# locally available. # status_withdrawn Withdrawn
# parameter rg_artist: Artist name of release group # status_expunged Expunged release
# (optional) # status_cancelled Cancelled release
# parameter rg_title: Title of release group (optional) # status_unknown Status of release is not specified
# parameter rgid: MusicBrainz release-group ID # fmttracks `printf` expression for track number
# (optional) # fmtmedia `printf` expression for media number
# Then, there are several format strings that indicate the status of a release. # fmtyear `printf` expression for release year
# The status are implicit from the parameter names: # fmtcountry `printf` expression for release country
# parameter release_official # fmtlabel `printf` expression for label
# parameter release_promotion # fmttitle `printf` expression for release title
# parameter release_bootleg # fmtartist `printf` expression for release artist credits
# parameter release_pseudo
# parameter release_withdrawn
# parameter release_expunged
# parameter release_cancelled
# #
# The input to this awk program is a sequence of lines containing the following # The input to this awk program is a sequence of lines containing the following
# fields: # fields:
@@ -44,68 +40,62 @@
# Field 9: Release title # Field 9: Release title
# Field 10: Artist as credited # Field 10: Artist as credited
# #
# The output is a sequence of tab-delimited lines with the fields: # The output of this script is a sequence of tab-delimited lines. The first
# Field 1: Sort value to sort release groups # `RV_FMT_CNT` fields are those that will be displayed to the user. The
# Field 2: The flag `format_local` if the release is accessible locally, and "" # following fields are
# else. # - sort key (release year)
# Field 3: Release line # - MusicBrainz release-group ID if specified, else the constant "0"
# Field 4: MusicBrainz release-group ID if present, else "0" # - MusicBrainz release ID
# Field 5: MusicBrainz release ID followed by ":" and then a path to the # - Path to decoration file if some music of that release is locally available
# decoration file (if it exists)
@include "lib/awk/lib.awk"
BEGIN { BEGIN {
OFS="\t" OFS="\t"
local_releases[0] = 0 flagged[0] = 0
delete local_releases[0] delete flagged[0]
if (file_local_releases) { if (flagfile) {
while ((getline < file_local_releases) == 1) while ((getline < flagfile) == 1)
local_releases[$1] = $2 flagged[$1] = $2
close(file_local_releases) close(flagfile)
} }
} }
{ {
id = $1 # Read data
line = format
mbid = $1
status = $2 status = $2
year = substr($3, 1, 4) + 0 year = $3 ? sprintf(fmtyear, substr($3, 1, 4) + 0) : ""
year = year == 0 ? "" : year
covercount = $4 covercount = $4
label = $5 label = $5 ? sprintf(fmtlabel, escape($5)) : ""
trackcnt = $6 tracks = $6 ? sprintf(fmttracks, escape($6)) : ""
media = $7 media = $7 ? sprintf(fmtmedia, escape($7)) : ""
country = $8 country = $8 ? sprintf(fmtcountry, escape($8)) : ""
title = $9 title = escape($9) != origtitle ? sprintf(fmttitle, escape($9)) : ""
artist = $10 artist = escape($10) != origartist ? sprintf(fmtartist, escape($10)) : ""
switch (status) { sort = $3 + 0
case "Official": line_status = release_official; break # Transform data and fill placeholders
case "Promotion": line_status = release_promotion; break if (flagged[mbid])
case "Bootleg": line_status = release_bootleg; break gsub("<<flag>>", flag_local, line)
case "Pseudo-release": line_status = release_pseudo; break
case "Withdrawn": line_status = release_withdrawn; break
case "Expunged": line_status = release_expunged; break
case "Cancelled": line_status = release_cancelled; break
default: line_status = ""
}
line = format_release
if (artist != rg_artist && title != rg_title)
line = line "\t" format_release_title_artist
else if (artist != rg_artist && title == rg_title)
line = line "\t" format_release_artist
else if (artist == rg_artist && title != rg_title)
line = line "\t" format_release_title
else else
line = line "\t" gsub("<<flag>>", flag_nolocal, line)
switch (status) {
gsub("<<status>>", line_status, line) case "Official": s = status_official; break
gsub("<<year>>", year, line) case "Promotion": s = status_promotion; break
gsub("<<tracks>>", trackcnt, line) case "Bootleg": s = status_bootleg; break
case "Pseudo-release": s = status_pseudo; break
case "Withdrawn": s = status_withdrawn; break
case "Expunged": s = status_expunged; break
case "Cancelled": s = status_cancelled; break
default: s = status_unknown
}
gsub("<<status>>", s, line)
gsub("<<tracks>>", tracks, line)
gsub("<<media>>", media, line) gsub("<<media>>", media, line)
gsub("&", "\\\\&", label) gsub("<<year>>", year, line)
gsub("<<label>>", label, line)
gsub("&", "\\\\&", title)
gsub("<<title>>", title, line)
gsub("&", "\\\\&", artist)
gsub("<<artist>>", artist, line)
gsub("<<country>>", country, line) gsub("<<country>>", country, line)
sortk = year ? year : 0 gsub("<<label>>", label, line)
l = local_releases[id] ? format_local : "" gsub("<<title>>", title, line)
print sortk, l, line, rgid ? rgid : "0", id ":" local_releases[id] gsub("<<artist>>", artist, line)
print line, sort, releasegroupid ? releasegroupid : "0", mbid, flagged[mbid] ? flagged[mbid] : ""
} }

7
src/lib/awk/lib.awk Normal file
View File

@@ -0,0 +1,7 @@
# Awk methods commonly used
# Escape string
function escape(s) {
gsub("&", "\\\\&", s)
return s
}

View File

@@ -83,6 +83,21 @@ MODE_INSERT="show"
# Load keys # Load keys
. "sh/keys.sh" . "sh/keys.sh"
# Load configuration
. "sh/config.sh"
# Load sorting methods
. "sh/sort.sh"
# Load theme
. "sh/theme.sh"
# Load tools
. "sh/tools.sh"
# Load AWK scripts
. "sh/awk.sh"
# Command-line options that may only be used internally. # Command-line options that may only be used internally.
# --lines # --lines
# --playback # --playback
@@ -126,6 +141,7 @@ case "${1:-}" in
# @argument $3: MusicBrainz ID of current object # @argument $3: MusicBrainz ID of current object
# @argument $4: MusicBrainz ID of selected object # @argument $4: MusicBrainz ID of selected object
# @argument $5: Path to decoration file # @argument $5: Path to decoration file
info "call to $*"
shift shift
playback "$@" playback "$@"
exit 0 exit 0
@@ -350,18 +366,6 @@ case "${1:-}" in
;; ;;
esac esac
# Load configuration
. "sh/config.sh"
# Load theme
. "sh/theme.sh"
# Load tools
. "sh/tools.sh"
# Load AWK scripts
. "sh/awk.sh"
# Non-interactive user commands intended to the user. These commands do not # Non-interactive user commands intended to the user. These commands do not
# require temporary files, fzf, nor the mpv instance. # require temporary files, fzf, nor the mpv instance.
case "${1:-}" in case "${1:-}" in
@@ -565,11 +569,11 @@ while true; do
--border="bold" \ --border="bold" \
--border-label="Select artist" \ --border-label="Select artist" \
--preview-window="right,25%,border-left,wrap,<30(hidden)" \ --preview-window="right,25%,border-left,wrap,<30(hidden)" \
--preview="$0 --preview $VIEW_SELECT_ARTIST {3}" \ --preview="$0 --preview $VIEW_SELECT_ARTIST {4}" \
--delimiter="\t" \ --delimiter="\t" \
--prompt="$SEARCH_PROMPT" \ --prompt="$SEARCH_PROMPT" \
--margin="5%,20%" \ --margin="5%,20%" \
--accept-nth="{3}" \ --accept-nth="{4}" \
--with-nth="{1}" || true --with-nth="{1}" || true
) )
lines=$(echo "$sel" | wc -l) lines=$(echo "$sel" | wc -l)
@@ -599,20 +603,20 @@ while true; do
--bind="$KEYS_N_BOT:last" \ --bind="$KEYS_N_BOT:last" \
--bind="$KEYS_N_TOP:first" \ --bind="$KEYS_N_TOP:first" \
--bind="$KEYS_OUT,$KEYS_N_OUT,$KEYS_QUIT,$KEYS_N_QUIT:print($LASTVIEW)+print($LASTARG)+print($VIEW_PLAYLIST)+print()+accept" \ --bind="$KEYS_OUT,$KEYS_N_OUT,$KEYS_QUIT,$KEYS_N_QUIT:print($LASTVIEW)+print($LASTARG)+print($VIEW_PLAYLIST)+print()+accept" \
--bind="$KEYS_SELECT_ARTIST:transform:$0 --action-gotoartist $MODE_NORMAL $VIEW_PLAYLIST {2} {3}" \ --bind="$KEYS_SELECT_ARTIST:transform:$0 --action-gotoartist $MODE_NORMAL $VIEW_PLAYLIST {3} {4}" \
--bind="$KEYS_LIST_ARTISTS:print($VIEW_LIST_ARTISTS)+accept" \ --bind="$KEYS_LIST_ARTISTS:print($VIEW_LIST_ARTISTS)+accept" \
--bind="$KEYS_LIST_ALBUMS:print($VIEW_LIST_ALBUMS)+accept" \ --bind="$KEYS_LIST_ALBUMS:print($VIEW_LIST_ALBUMS)+accept" \
--bind="$KEYS_SEARCH_ARTIST:print($VIEW_SEARCH_ARTIST)+accept" \ --bind="$KEYS_SEARCH_ARTIST:print($VIEW_SEARCH_ARTIST)+accept" \
--bind="$KEYS_SEARCH_ALBUM:print($VIEW_SEARCH_ALBUM)+accept" \ --bind="$KEYS_SEARCH_ALBUM:print($VIEW_SEARCH_ALBUM)+accept" \
--bind="$KEYS_BROWSE:execute-silent:open \"https://musicbrainz.org/\track/{r3}\"" \ --bind="$KEYS_BROWSE:execute-silent:open \"https://musicbrainz.org/\track/{r3}\"" \
--bind="$KEYS_OPEN:execute-silent:open \"\$(dirname {4})\"" \ --bind="$KEYS_OPEN:execute-silent:open \"\$(dirname {5})\"" \
--bind="$KEYS_N_YANK:execute-silent:printf {3} | $CLIP)" \ --bind="$KEYS_N_YANK:execute-silent:printf {4} | $CLIP)" \
--bind="$KEYS_YANK_CURRENT:execute-silent:printf {2} | $CLIP" \ --bind="$KEYS_YANK_CURRENT:execute-silent:printf {3} | $CLIP" \
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $VIEW_PLAYLIST" \ --bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $VIEW_PLAYLIST" \
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \ --bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \ --bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \ --bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
--bind="$KEYS_PLAYBACK,$KEYS_N_PLAYBACK:transform($0 --playback $VIEW_PLAYLIST {2} {3} {4})+$FZF_RELOAD_PLAYLIST+$FZF_POS_PLAYLIST" \ --bind="$KEYS_PLAYBACK,$KEYS_N_PLAYBACK:transform($0 --playback $VIEW_PLAYLIST {3} {4} {5})+$FZF_RELOAD_PLAYLIST+$FZF_POS_PLAYLIST" \
--bind="$KEYS_PLAYLIST_RELOAD:$FZF_RELOAD_PLAYLIST+$FZF_POS_PLAYLIST" \ --bind="$KEYS_PLAYLIST_RELOAD:$FZF_RELOAD_PLAYLIST+$FZF_POS_PLAYLIST" \
--bind="$KEYS_PLAYLIST_REMOVE:execute-silent($0 --playlist $PLAYLIST_CMD_REMOVE)+$FZF_RELOAD_PLAYLIST" \ --bind="$KEYS_PLAYLIST_REMOVE:execute-silent($0 --playlist $PLAYLIST_CMD_REMOVE)+$FZF_RELOAD_PLAYLIST" \
--bind="$KEYS_PLAYLIST_UP:execute-silent($0 --playlist $PLAYLIST_CMD_UP)+up+$FZF_RELOAD_PLAYLIST" \ --bind="$KEYS_PLAYLIST_UP:execute-silent($0 --playlist $PLAYLIST_CMD_UP)+up+$FZF_RELOAD_PLAYLIST" \
@@ -625,7 +629,7 @@ while true; do
--bind="$KEYS_PLAYLIST_GOTO_RELEASE:print($VIEW_RELEASE)+accept" \ --bind="$KEYS_PLAYLIST_GOTO_RELEASE:print($VIEW_RELEASE)+accept" \
--delimiter="\t" \ --delimiter="\t" \
--with-nth="{1}" \ --with-nth="{1}" \
--accept-nth="{2}" || true --accept-nth="{3}" || true
) )
VIEW="$(echo "$sel" | head -1)" VIEW="$(echo "$sel" | head -1)"
ARGS="$(echo "$sel" | head -2 | tail -1)" ARGS="$(echo "$sel" | head -2 | tail -1)"
@@ -667,11 +671,11 @@ while true; do
--bind="$KEYS_N_UP:transform:$IN_NORMAL_MODE && echo up || $PUT_FZF_KEY_LOGIC" \ --bind="$KEYS_N_UP:transform:$IN_NORMAL_MODE && echo up || $PUT_FZF_KEY_LOGIC" \
--bind="$KEYS_N_BOT:transform:$IN_NORMAL_MODE && echo last || $PUT_FZF_KEY_LOGIC" \ --bind="$KEYS_N_BOT:transform:$IN_NORMAL_MODE && echo last || $PUT_FZF_KEY_LOGIC" \
--bind="$KEYS_N_TOP:transform:$IN_NORMAL_MODE && echo first || $PUT_FZF_KEY_LOGIC" \ --bind="$KEYS_N_TOP:transform:$IN_NORMAL_MODE && echo first || $PUT_FZF_KEY_LOGIC" \
--bind="$KEYS_IN:transform:[ {3} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {3} \"+1\"" \ --bind="$KEYS_IN:transform:[ {4} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {4} \"+1\"" \
--bind="$KEYS_OUT:transform:[ {2} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {2} \"-1\"" \ --bind="$KEYS_OUT:transform:[ {3} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {3} \"-1\"" \
--bind="$KEYS_N_IN:transform:$IN_NORMAL_MODE && ([ {3} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {3} \"+1\") || $PUT_FZF_KEY_LOGIC" \ --bind="$KEYS_N_IN:transform:$IN_NORMAL_MODE && ([ {4} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {4} \"+1\") || $PUT_FZF_KEY_LOGIC" \
--bind="$KEYS_N_OUT:transform:$IN_NORMAL_MODE && ([ {2} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {2} \"-1\") || $PUT_FZF_KEY_LOGIC" \ --bind="$KEYS_N_OUT:transform:$IN_NORMAL_MODE && ([ {3} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {3} \"-1\") || $PUT_FZF_KEY_LOGIC" \
--bind="$KEYS_SELECT_ARTIST:transform:$0 --action-gotoartist $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {2} {3}" \ --bind="$KEYS_SELECT_ARTIST:transform:$0 --action-gotoartist $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {3} {4}" \
--bind="$KEYS_LIST_ARTISTS:transform:$0 --action-draw \$FZF_INPUT_STATE $VIEW_LIST_ARTISTS" \ --bind="$KEYS_LIST_ARTISTS:transform:$0 --action-draw \$FZF_INPUT_STATE $VIEW_LIST_ARTISTS" \
--bind="$KEYS_LIST_ALBUMS:transform:$0 --action-draw \$FZF_INPUT_STATE $VIEW_LIST_ALBUMS" \ --bind="$KEYS_LIST_ALBUMS:transform:$0 --action-draw \$FZF_INPUT_STATE $VIEW_LIST_ALBUMS" \
--bind="$KEYS_SEARCH_ARTIST:transform:$0 --action-draw $MODE_INSERT $VIEW_SEARCH_ARTIST" \ --bind="$KEYS_SEARCH_ARTIST:transform:$0 --action-draw $MODE_INSERT $VIEW_SEARCH_ARTIST" \
@@ -690,7 +694,7 @@ $VIEW_SEARCH_ALBUM) $0 --action-draw $MODE_NORMAL $VIEW_LIST_ALBUMS ;;
esac" \ esac" \
--bind="$KEYS_FILTER:transform:$0 --action-filter $FZF_CURRENT_MODE $FZF_CURRENT_VIEW" \ --bind="$KEYS_FILTER:transform:$0 --action-filter $FZF_CURRENT_MODE $FZF_CURRENT_VIEW" \
--bind="$KEYS_BROWSE:execute-silent: --bind="$KEYS_BROWSE:execute-silent:
[ {3} ] || exit 0 [ {4} ] || exit 0
case $FZF_CURRENT_VIEW in case $FZF_CURRENT_VIEW in
$VIEW_LIST_ARTISTS | $VIEW_SEARCH_ARTIST) t=artist ;; $VIEW_LIST_ARTISTS | $VIEW_SEARCH_ARTIST) t=artist ;;
$VIEW_ARTIST | $VIEW_SEARCH_ALBUM | $VIEW_LIST_ALBUMS) t=release-group ;; $VIEW_ARTIST | $VIEW_SEARCH_ALBUM | $VIEW_LIST_ALBUMS) t=release-group ;;
@@ -699,25 +703,24 @@ case $FZF_CURRENT_VIEW in
esac esac
open \"https://musicbrainz.org/\$t/{r3}\"" \ open \"https://musicbrainz.org/\$t/{r3}\"" \
--bind="$KEYS_OPEN:execute-silent: --bind="$KEYS_OPEN:execute-silent:
[ {4} ] || exit 0 [ {5} ] || exit 0
open \"\$(dirname {4})\"" \ open \"\$(dirname {5})\"" \
--bind="$KEYS_N_YANK:transform:$IN_NORMAL_MODE && echo \"execute-silent(printf {3} | $CLIP)\" || $PUT_FZF_KEY_LOGIC" \ --bind="$KEYS_N_YANK:transform:$IN_NORMAL_MODE && echo \"execute-silent(printf {4} | $CLIP)\" || $PUT_FZF_KEY_LOGIC" \
--bind="$KEYS_YANK_CURRENT:execute-silent:printf {2} | $CLIP" \ --bind="$KEYS_YANK_CURRENT:execute-silent:printf {3} | $CLIP" \
--bind="$KEYS_SHOW_PLAYLIST:transform:echo \"print($VIEW_PLAYLIST)+print()+print($FZF_CURRENT_VIEW)+print({2})+accept\"" \ --bind="$KEYS_SHOW_PLAYLIST:transform:echo \"print($VIEW_PLAYLIST)+print()+print($FZF_CURRENT_VIEW)+print({3})+accept\"" \
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $FZF_CURRENT_VIEW" \ --bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $FZF_CURRENT_VIEW" \
--bind="$KEYS_REFRESH:execute-silent($0 --remove-from-cache $FZF_CURRENT_VIEW {2} {3})+transform:$0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {2}" \ --bind="$KEYS_REFRESH:execute-silent($0 --remove-from-cache $FZF_CURRENT_VIEW {3} {4})+transform:$0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {3}" \
--bind="$KEYS_QUIT:print($VIEW_QUIT)+accept" \ --bind="$KEYS_QUIT:print($VIEW_QUIT)+accept" \
--bind="$KEYS_N_QUIT:transform:$IN_NORMAL_MODE && ($IN_LIST_ARTISTS_VIEW && echo \"print($VIEW_QUIT)+accept\" || $0 --action-draw $MODE_NORMAL $VIEW_LIST_ARTISTS) || $PUT_FZF_KEY_LOGIC" \ --bind="$KEYS_N_QUIT:transform:$IN_NORMAL_MODE && ($IN_LIST_ARTISTS_VIEW && echo \"print($VIEW_QUIT)+accept\" || $0 --action-draw $MODE_NORMAL $VIEW_LIST_ARTISTS) || $PUT_FZF_KEY_LOGIC" \
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \ --bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \ --bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
--bind="$KEYS_PREVIEW_OPEN:show-preview" \ --bind="$KEYS_PREVIEW_OPEN:show-preview" \
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \ --bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
--bind="$KEYS_PLAYBACK:transform:$0 --playback $FZF_CURRENT_VIEW {2} {3} {4}" \ --bind="$KEYS_PLAYBACK:transform:$0 --playback $FZF_CURRENT_VIEW {3} {4} {5}" \
--bind="$KEYS_N_PLAYBACK:transform:$IN_NORMAL_MODE && $0 --playback $FZF_CURRENT_VIEW {2} {3} {4} || $PUT_FZF_KEY_LOGIC" \ --bind="$KEYS_N_PLAYBACK:transform:$IN_NORMAL_MODE && $0 --playback $FZF_CURRENT_VIEW {3} {4} {5} || $PUT_FZF_KEY_LOGIC" \
--bind="W:execute-silent:echo 1 >> /tmp/foo; echo $FZF_CURRENT_VIEW >> /tmp/foo; echo 2 >> /tmp/foo" \
--bind="change:execute-silent($0 --mbsearch $FZF_CURRENT_VIEW &)+reload:$0 --lines $FZF_CURRENT_VIEW" \ --bind="change:execute-silent($0 --mbsearch $FZF_CURRENT_VIEW &)+reload:$0 --lines $FZF_CURRENT_VIEW" \
--preview-window="right,25%,border-left,wrap,<30(hidden)" \ --preview-window="right,25%,border-left,wrap,<30(hidden)" \
--preview="$0 --preview $FZF_CURRENT_VIEW {3}" \ --preview="$0 --preview $FZF_CURRENT_VIEW {4}" \
--delimiter="\t" \ --delimiter="\t" \
--with-nth="{1}" || true --with-nth="{1}" || true
) )

View File

@@ -1,5 +1,6 @@
# The code below is used together with `scripts/build.sh`to internalize the awk # The code below is used together with `scripts/build.sh`to internalize the awk
# scripts. See the awk sources for more information. # scripts. See the awk sources for more information.
if [ ! "${AWK_LOADED:-}" ]; then if [ ! "${AWK_LOADED:-}" ]; then
AWK_ARTISTS=$( AWK_ARTISTS=$(
cat <<'EOF' cat <<'EOF'
@@ -31,3 +32,235 @@ EOF
export AWK_LOADED=1 export AWK_LOADED=1
fi fi
# Themed awk script to generate list of artists
#
# @argument $1: Sort specification (may be one of SORT_NO, SORT_NAME,
# SORT_SORTNAME)
awk_artists() {
case "${1:-}" in
"$SORT_ARTIST" | "$SORT_ARTIST_SORTNAME") s="$SORT_ALPHA" ;;
*) s="$SORT_NO" ;;
esac
cat |
awk \
-F "\t" \
-v sortby="${1:-}" \
-v flagfile="${LOCALDATA_ARTISTS:-}" \
-v format="$AV_FMT" \
-v flag_local="$AV_FMT_FLAG_LOCAL" \
-v flag_nolocal="$AV_FMT_FLAG_NO_LOCAL" \
-v type_person="$AV_FMT_TYPE_PERSON" \
-v type_group="$AV_FMT_TYPE_GROUP" \
-v fmtname="$AV_FMT_NAME" \
-v fmtdisambiguation="$AV_FMT_DISAMBIGUATION" \
"$AWK_ARTISTS" |
column -t -s "$(printf '\t')" -R "$AV_FMT_RIGHTALIGN" -l "$AV_FMT_CNT" |
sort_list "$s"
}
# Themed awk script to generate artist header
awk_artist_header() {
cat |
awk \
-F "\t" \
-v flagfile="${LOCALDATA_ARTISTS:-}" \
-v format="$HEADER_ARTIST_FMT" \
-v flag_local="$HEADER_ARTIST_FMT_FLAG_LOCAL" \
-v flag_nolocal="$HEADER_ARTIST_FMT_FLAG_NO_LOCAL" \
-v type_person="$HEADER_ARTIST_FMT_TYPE_PERSON" \
-v type_group="$HEADER_ARTIST_FMT_TYPE_GROUP" \
-v fmtname="$HEADER_ARTIST_FMT_NAME" \
-v fmtdisambiguation="$HEADER_ARTIST_FMT_DISAMBIGUATION" \
"$AWK_ARTISTS" |
column -t -s "$(printf '\t')" -R "$HEADER_ARTIST_FMT_RIGHTALIGN" -l "$HEADER_ARTIST_FMT_CNT" |
cut -d "$(printf '\t')" -f 1
}
# Themed awk script to generate list of release groups
#
# @argument $1: Sort specification (may be one of SORT_NO, SORT_RG_TITLE,
# SORT_RG_YEAR)
# @argument $2: MusicBrainz artist ID (optional)
# @argument $3: Artist credit name (optional)
awk_releasegroups() {
case "${1:-}" in
"$SORT_RG_TITLE") s="$SORT_ALPHA" ;;
"$SORT_RG_YEAR") s="$SORT_NUMERIC" ;;
*) s="$SORT_NO" ;;
esac
cat |
awk \
-F "\t" \
-v sortby="${1:-}" \
-v artistid="${2:-}" \
-v origartist="${3:-}" \
-v flagfile="${LOCALDATA_RELEASEGROUPS:-}" \
-v format="$RGV_FMT" \
-v flag_local="$RGV_FMT_FLAG_LOCAL" \
-v flag_nolocal="$RGV_FMT_FLAG_NO_LOCAL" \
-v type_single="$RGV_FMT_TYPE_SINGLE" \
-v type_album="$RGV_FMT_TYPE_ALBUM" \
-v type_ep="$RGV_FMT_TYPE_EP" \
-v type_broadcast="$RGV_FMT_TYPE_BROADCAST" \
-v type_other="$RGV_FMT_TYPE_OTHER" \
-v type_unknown="$RGV_FMT_TYPE_UNKNOWN" \
-v hassecondary_yes="$RGV_FMT_HASSECONDARY_YES" \
-v hassecondary_no="$RGV_FMT_HASSECONDARY_NO" \
-v fmtsecondary="$RGV_FMT_SECONDARY" \
-v secondary_soundtrack="$RGV_FMT_SECONDARY_SOUNDTRACK" \
-v secondary_spokenword="$RGV_FMT_SECONDARY_SPOKENWORD" \
-v secondary_interview="$RGV_FMT_SECONDARY_INTERVIEW" \
-v secondary_audiobook="$RGV_FMT_SECONDARY_AUDIOBOOK" \
-v secondary_audiodrama="$RGV_FMT_SECONDARY_AUDIODRAMA" \
-v secondary_live="$RGV_FMT_SECONDARY_LIVE" \
-v secondary_remix="$RGV_FMT_SECONDARY_REMIX" \
-v secondary_djmix="$RGV_FMT_SECONDARY_DJMIX" \
-v secondary_mixtape="$RGV_FMT_SECONDARY_MIXTAPE" \
-v secondary_demo="$RGV_FMT_SECONDARY_DEMO" \
-v secondary_fieldrec="$RGV_FMT_SECONDARY_FIELDREC" \
-v fmttitle="$RGV_FMT_TITLE" \
-v fmtartist="$RGV_FMT_ARTIST" \
-v fmtyear="$RGV_FMT_YEAR" \
"$AWK_RELEASEGROUPS" |
column -t -s "$(printf '\t')" -R "$RGV_FMT_RIGHTALIGN" -l "$RGV_FMT_CNT" |
sort_list "$s"
}
# Themed awk script to generate release-group header
awk_releasegroup_header() {
cat |
awk \
-F "\t" \
-v flagfile="${LOCALDATA_RELEASEGROUPS:-}" \
-v format="$HEADER_RG_FMT" \
-v flag_local="$HEADER_RG_FMT_FLAG_LOCAL" \
-v flag_nolocal="$HEADER_RG_FMT_FLAG_NO_LOCAL" \
-v type_single="$HEADER_RG_FMT_TYPE_SINGLE" \
-v type_album="$HEADER_RG_FMT_TYPE_ALBUM" \
-v type_ep="$HEADER_RG_FMT_TYPE_EP" \
-v type_broadcast="$HEADER_RG_FMT_TYPE_BROADCAST" \
-v type_other="$HEADER_RG_FMT_TYPE_OTHER" \
-v type_unknown="$HEADER_RG_FMT_TYPE_UNKNOWN" \
-v hassecondary_yes="$HEADER_RG_FMT_HASSECONDARY_YES" \
-v hassecondary_no="$HEADER_RG_FMT_HASSECONDARY_NO" \
-v fmtsecondary="$HEADER_RG_FMT_SECONDARY" \
-v secondary_soundtrack="$HEADER_RG_FMT_SECONDARY_SOUNDTRACK" \
-v secondary_spokenword="$HEADER_RG_FMT_SECONDARY_SPOKENWORD" \
-v secondary_interview="$HEADER_RG_FMT_SECONDARY_INTERVIEW" \
-v secondary_audiobook="$HEADER_RG_FMT_SECONDARY_AUDIOBOOK" \
-v secondary_audiodrama="$HEADER_RG_FMT_SECONDARY_AUDIODRAMA" \
-v secondary_live="$HEADER_RG_FMT_SECONDARY_LIVE" \
-v secondary_remix="$HEADER_RG_FMT_SECONDARY_REMIX" \
-v secondary_djmix="$HEADER_RG_FMT_SECONDARY_DJMIX" \
-v secondary_mixtape="$HEADER_RG_FMT_SECONDARY_MIXTAPE" \
-v secondary_demo="$HEADER_RG_FMT_SECONDARY_DEMO" \
-v secondary_fieldrec="$HEADER_RG_FMT_SECONDARY_FIELDREC" \
-v fmttitle="$HEADER_RG_FMT_TITLE" \
-v fmtartist="$HEADER_RG_FMT_ARTIST" \
-v fmtyear="$HEADER_RG_FMT_YEAR" \
"$AWK_RELEASEGROUPS" |
column -t -s "$(printf '\t')" -R "$HEADER_RG_FMT_RIGHTALIGN" -l "$HEADER_RG_FMT_CNT" |
cut -d "$(printf '\t')" -f 1
}
# Themed awk script to generate list of releases
#
# @argument $1: MusicBrainz release-group ID (optional)
# @argument $2: Title of release group (optional)
# @argument $3: Artist credit name of release group
awk_releases() {
cat |
awk \
-F "\t" \
-v releasegroupid="${1:-}" \
-v origtitle="${2:-}" \
-v origartist="${3:-}" \
-v flagfile="${LOCALDATA_RELEASES:-}" \
-v format="$RV_FMT" \
-v flag_local="$RV_FMT_FLAG_LOCAL" \
-v flag_nolocal="$RV_FMT_FLAG_NO_LOCAL" \
-v status_official="$RV_FMT_STATUS_OFFICIAL" \
-v status_promo="$RV_FMT_STATUS_PROMO" \
-v status_bootleg="$RV_FMT_STATUS_BOOTLEG" \
-v status_pseudo="$RV_FMT_STATUS_PSEUDO" \
-v status_withdrawn="$RV_FMT_STATUS_WITHDRAWN" \
-v status_expunged="$RV_FMT_STATUS_EXPUNGED" \
-v status_cancelled="$RV_FMT_STATUS_CANCELLED" \
-v status_unknown="$RV_FMT_STATUS_UNKNOWN" \
-v fmttracks="$RV_FMT_TRACKS" \
-v fmtmedia="$RV_FMT_MEDIA" \
-v fmtyear="$RV_FMT_YEAR" \
-v fmtcountry="$RV_FMT_COUNTRY" \
-v fmtlabel="$RV_FMT_LABEL" \
-v fmttitle="$RV_FMT_TITLE" \
-v fmtartist="$RV_FMT_ARTIST" \
"$AWK_RELEASES" |
column -t -s "$(printf '\t')" -R "$RV_FMT_RIGHTALIGN" -l "$RV_FMT_CNT" |
sort -t "$(printf '\t')" -k 2,2
}
# Themed awk script to generate release header
awk_release_header() {
cat |
awk \
-F "\t" \
-v flagfile="${LOCALDATA_RELEASES:-}" \
-v format="$HEADER_R_FMT" \
-v flag_local="$HEADER_R_FMT_FLAG_LOCAL" \
-v flag_nolocal="$HEADER_R_FMT_FLAG_NO_LOCAL" \
-v status_official="$HEADER_R_FMT_STATUS_OFFICIAL" \
-v status_promo="$HEADER_R_FMT_STATUS_PROMO" \
-v status_bootleg="$HEADER_R_FMT_STATUS_BOOTLEG" \
-v status_pseudo="$HEADER_R_FMT_STATUS_PSEUDO" \
-v status_withdrawn="$HEADER_R_FMT_STATUS_WITHDRAWN" \
-v status_expunged="$HEADER_R_FMT_STATUS_EXPUNGED" \
-v status_cancelled="$HEADER_R_FMT_STATUS_CANCELLED" \
-v status_unknown="$HEADER_R_FMT_STATUS_UNKNOWN" \
-v fmttracks="$HEADER_R_FMT_TRACKS" \
-v fmtmedia="$HEADER_R_FMT_MEDIA" \
-v fmtyear="$HEADER_R_FMT_YEAR" \
-v fmtcountry="$HEADER_R_FMT_COUNTRY" \
-v fmtlabel="$HEADER_R_FMT_LABEL" \
-v fmttitle="$HEADER_R_FMT_TITLE" \
-v fmtartist="$HEADER_R_FMT_ARTIST" \
"$AWK_RELEASES" |
column -t -s "$(printf '\t')" -R "$HEADER_R_FMT_RIGHTALIGN" -l "$HEADER_R_FMT_CNT" |
cut -d "$(printf '\t')" -f 1
}
# Themed awk script to generate list of tracks
#
# @argument $1: Path to file with MusicBrainz track IDs "tab" decoration file
# of locally playable audio tracks (optional)
awk_recordings() {
cat |
awk \
-F "\t" \
-v flagfile="${1:-}" \
-v format="$REC_FMT" \
-v flag_local="$REC_FMT_FLAG_LOCAL" \
-v flag_nolocal="$REC_FMT_FLAG_NO_LOCAL" \
-v fmtmedia="$REC_FMT_MEDIA" \
-v fmtnr="$REC_FMT_NR" \
-v fmttitle="$REC_FMT_TITLE" \
-v fmtartist="$REC_FMT_ARTIST" \
-v fmtduration="$REC_FMT_DURATION" \
"$AWK_RECORDINGS" |
column -t -s "$(printf '\t')" -R "$REC_FMT_RIGHTALIGN" -l "$REC_FMT_CNT"
}
# Themed awk script to generate list of tracks for playlist view
awk_playlist() {
cat |
awk \
-F "\t" \
-v format="$PLYLST_FMT" \
-v playing_yes="$PLYLST_FMT_PLAYING_YES" \
-v playing_no="$PLYLST_FMT_PLAYING_NO" \
-v fmttitle="$PLYLST_FMT_TITLE" \
-v fmtartist="$PLYLST_FMT_ARTIST" \
-v fmtduration="$PLYLST_FMT_DURATION" \
"$AWK_RECORDINGS" |
column -t -s "$(printf '\t')" -R "$PLYLST_FMT_RIGHTALIGN" -l "$PLYLST_FMT_CNT"
}

View File

@@ -11,6 +11,7 @@
# the respective key bindings. # the respective key bindings.
# - `src/sh/keys.sh`: Configuration of key bindings to certain actions # - `src/sh/keys.sh`: Configuration of key bindings to certain actions
# - `src/sh/theme.sh`: Configuration of theme # - `src/sh/theme.sh`: Configuration of theme
# - `src/sh/sort.sh`: List sorting
CONFIGFILE_DEFAULT="$HOME/.config/$APP_NAME/config" CONFIGFILE_DEFAULT="$HOME/.config/$APP_NAME/config"
CONFIGFILE="${CONFIGFILE:-"$CONFIGFILE_DEFAULT"}" CONFIGFILE="${CONFIGFILE:-"$CONFIGFILE_DEFAULT"}"
[ "$CONFIGFILE" != "$CONFIGFILE_DEFAULT" ] && [ ! -f "$CONFIGFILE" ] && err "The configuration file manually specified with the environment variable CONFIGFILE=($CONFIGFILE) does not exist." && exit 1 [ "$CONFIGFILE" != "$CONFIGFILE_DEFAULT" ] && [ ! -f "$CONFIGFILE" ] && err "The configuration file manually specified with the environment variable CONFIGFILE=($CONFIGFILE) does not exist." && exit 1

View File

@@ -9,12 +9,12 @@ QUERY_LOCAL="${QUERY_LOCAL:-"$(printf "'%s'" "$FORMAT_LOCAL" | __clean_filter)"}
# The following variables store preset strings derived from the theme (see # The following variables store preset strings derived from the theme (see
# `src/sh/theme.sh`), and used in the assignment of the default filters. # `src/sh/theme.sh`), and used in the assignment of the default filters.
q_has_seconary="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "" | __clean_filter)" q_has_seconary="$(printf "%s" "$RGV_FMT_HASSECONDARY_YES" | __clean_filter)"
q_album="$(printf "%s" "$FORMAT_TYPE_ALBUM" | __clean_filter)" q_album="$(printf "%s" "$RGV_FMT_TYPE_ALBUM" | __clean_filter)"
q_ep=$(printf "%s" "$FORMAT_TYPE_EP" | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g") q_ep="$(printf "%s" "$RGV_FMT_TYPE_EP" | __clean_filter)"
q_single=$(printf "%s" "$FORMAT_TYPE_SINGLE" | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g") q_single="$(printf "%s" "$RGV_FMT_TYPE_SINGLE" | __clean_filter)"
if printf "$RV_FORMAT" | grep -q "<<status>>"; then if printf "$RV_FMT" | grep -q "<<status>>"; then
q_official=$(printf "'%s'" "$FORMAT_STATUS_OFFICIAL" | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g") q_official="$(printf "'%s'" "$RV_FMT_STATUS_OFFICIAL" | __clean_filter)"
fi fi
export QUERY_LOCAL export QUERY_LOCAL

View File

@@ -11,39 +11,43 @@ fzf_command_set_header() {
"$VIEW_LIST_ARTISTS") header="Search locally available artist" ;; "$VIEW_LIST_ARTISTS") header="Search locally available artist" ;;
"$VIEW_LIST_ALBUMS") header="Search locally available album" ;; "$VIEW_LIST_ALBUMS") header="Search locally available album" ;;
"$VIEW_ARTIST") "$VIEW_ARTIST")
name="$(mb_artist "$mbid" | $JQ '.name')" header="$(
header=$(printf "$HEADER_ARTIST" "$name") mb_artist "$mbid" |
$JQ '[.id, type, .name, .disambiguation] | join("\t")' |
awk_artist_header
)"
;; ;;
"$VIEW_RELEASEGROUP") "$VIEW_RELEASEGROUP")
title="$(mb_releasegroup "$mbid" | header="$(
$JQ '.title')" mb_releasegroup "$mbid" |
artist="$(mb_releasegroup "$mbid" | $JQ '[
$JQ '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" .id,
header=$(printf "$HEADER_ARTIST_RELEASEGROUP" "$artist" "$title") ."primary-type",
(."secondary-types" // []|join(";")),
."first-release-date",
.title,
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
] | join("\t")' |
awk_releasegroup_header
)"
;; ;;
"$VIEW_RELEASE") "$VIEW_RELEASE")
title="$(mb_release "$mbid" | header="$(
$JQ '.title')" mb_release "$mbid" |
artist="$(mb_release "$mbid" | $JQ '[
$JQ '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" .id,
releaseinfo="$(mb_release "$mbid" | .status,
$JQ '[ .date,
.date[:4], ."cover-art-archive".count,
(."label-info" | map(.label.name) | unique | join(", ")), (."label-info" | map(.label.name) | unique | join(", ")),
(.media | map(."track-count") | add), (.media | map(."track-count") | add),
(.media | map(.format) | unique | join(", ")), (.media | map(.format) | unique | join(", ")),
.country .country,
] | join("\t")' | .title,
awk -F "\t" -v format="$HEADER_RELEASE_FORMAT" '{ (."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
gsub("&", "\\\\&") ] | join("\t")' |
sub("<<year>>", $1, format) awk_release_header
sub("<<label>>", $2, format) )"
sub("<<tracks>>", $3, format)
sub("<<media>>", $4, format)
sub("<<country>>", $5, format)
print format
}')"
header=$(printf "$HEADER_RELEASE" "$artist" "$title" "$releaseinfo")
;; ;;
esac esac
printf "+change-header(%s)" "${header:-"???"}" printf "+change-header(%s)" "${header:-"???"}"

View File

@@ -14,39 +14,7 @@ list_releasegroups() {
.title, .title,
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")) (."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
] | join("\t")' | ] | join("\t")' |
awk \ awk_releasegroups "$SORT_RG_DEFAULT" "$1" "$name"
-F "\t" \
-v artist="$name" \
-v artistid="$1" \
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
-v format_release="$RGV_RELEASE" \
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
-v format_year="$RGV_YEAR" \
-v format_album="$FORMAT_TYPE_ALBUM" \
-v format_single="$FORMAT_TYPE_SINGLE" \
-v format_ep="$FORMAT_TYPE_EP" \
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
-v format_other="$FORMAT_TYPE_OTHER" \
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_RELEASEGROUPS" |
sort -n -r |
cut -d "$(printf '\t')" -f 2- |
column -t -s "$(printf '\t')" |
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|'
} }
# List releases in given relese group # List releases in given relese group
@@ -70,95 +38,18 @@ list_releases() {
.title, .title,
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")) (."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
] | join("\t")' | ] | join("\t")' |
awk \ awk_releases "$1" "$title" "$artist"
-F "\t" \
-v file_local_releases="${LOCALDATA_RELEASES:-}" \
-v release_official="$FORMAT_STATUS_OFFICIAL" \
-v release_promotion="$FORMAT_STATUS_PROMO" \
-v release_bootleg="$FORMAT_STATUS_BOOTLEG" \
-v release_pseudo="$FORMAT_STATUS_PSEUDO" \
-v release_withdrawn="$FORMAT_STATUS_WITHDRAWN" \
-v release_expunged="$FORMAT_STATUS_EXPUNGED" \
-v release_cancelled="$FORMAT_STATUS_CANCELLED" \
-v format_release="$RV_FORMAT" \
-v format_release_title_artist="$RV_TITLE_ARTIST" \
-v format_release_title="$RV_TITLE" \
-v format_release_artist="$RV_ARTIST" \
-v rg_artist="$artist" \
-v rg_title="$title" \
-v rgid="$1" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_RELEASES" |
sort -n -r |
cut -d "$(printf '\t')" -f 2- |
column -t -s "$(printf '\t')" |
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2\t\3|'
} }
# List recordings of given release # List recordings of given release
# #
# argument $1: MusicBrainz release ID # argument $1: MusicBrainz release ID
list_recordings() { list_recordings() {
info "list recordings.."
deco="$(grep "$1" "$LOCALDATA_RELEASES" | cut -d "$(printf '\t')" -f 2)" deco="$(grep "$1" "$LOCALDATA_RELEASES" | cut -d "$(printf '\t')" -f 2)"
info "deco=$deco"
if [ "$deco" ]; then if [ "$deco" ]; then
rectmp=$(mktemp) rectmp=$(mktemp)
$JQ '.tracks | keys | join("\n")' "$deco" >"$rectmp" $JQ '.tracks | keys | join("\n")' "$deco" >"$rectmp"
info "rectmp=$rectmp"
info "$(cat "$rectmp")"
fi fi
info "going to awk..."
info "$(
mb_release "$1" |
$JQ \
--arg rid "$1" \
--arg deco "$deco" \
'.media |
length as $l |
.[] |
.position as $pos |
.tracks[] | [
$rid,
.id,
$l,
$pos,
.number,
.length,
.recording.title,
(.recording."artist-credit" | map([.name, .joinphrase] | join("")) | join("")),
$deco
] |
join("\t")'
)"
info "$(
mb_release "$1" |
$JQ \
--arg rid "$1" \
--arg deco "$deco" \
'.media |
length as $l |
.[] |
.position as $pos |
.tracks[] | [
$rid,
.id,
$l,
$pos,
.number,
.length,
.recording.title,
(.recording."artist-credit" | map([.name, .joinphrase] | join("")) | join("")),
$deco
] |
join("\t")' |
awk \
-F "\t" \
-v file_local_recordings="${rectmp:-}" \
-v format="$REC_FORMAT" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_RECORDINGS"
)"
mb_release "$1" | mb_release "$1" |
$JQ \ $JQ \
--arg rid "$1" \ --arg rid "$1" \
@@ -179,16 +70,7 @@ list_recordings() {
$deco $deco
] | ] |
join("\t")' | join("\t")' |
awk \ awk_recordings "${rectmp:-}"
-F "\t" \
-v file_local_recordings="${rectmp:-}" \
-v format="$REC_FORMAT" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_RECORDINGS" |
sort -k1,1n -k2,2g |
cut -d "$(printf '\t')" -f 2- |
column -t -s "$(printf '\t')" -R 3,4,7 |
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2\t\3|'
if [ "${rectmp:-}" ] && [ -f "$rectmp" ]; then if [ "${rectmp:-}" ] && [ -f "$rectmp" ]; then
rm -f "$rectmp" rm -f "$rectmp"
fi fi
@@ -210,15 +92,7 @@ list_local_releasegroups() {
list_artists_from_json() { list_artists_from_json() {
cat | cat |
$JQ 'map([.artist.id, .artist.type, .name] | join("\t")) | join("\n")' | $JQ 'map([.artist.id, .artist.type, .name] | join("\t")) | join("\n")' |
awk \ awk_artists "$SORT_NO"
-F "\t" \
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
-v format_person="$AV_PERSON" \
-v format_group="$AV_GROUP" \
-v format_disambiguation="$AV_DISAMBIGUATION" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_ARTISTS" |
column -t -s "$(printf '\t')" -l 2
} }
# Print playlist currently loaded # Print playlist currently loaded
@@ -227,27 +101,7 @@ list_playlist() {
[ "$count" -eq 0 ] && return 0 [ "$count" -eq 0 ] && return 0
mpvquery="" mpvquery=""
for i in $(seq 0 $((count - 1))); do for i in $(seq 0 $((count - 1))); do
mpvquery="$mpvquery\${playlist/$i/current}\t\${playlist/$i/title}\n" mpvquery="$mpvquery\${playlist/$i/title}\t\${playlist/$i/current}\n"
done done
mpvtmp=$(mktemp) __mpv_get "$mpvquery" | grep '.' | awk_playlist
# Get playlist information from mpv
__mpv_get "$mpvquery" | grep '.' >"$mpvtmp"
# Get MusicBrainz Track ID of current recording
current_id=$(grep "^yes" "$mpvtmp" | cut -d "$(printf '\t')" -f 3)
# Get file to be used in file_local_recordings
rectmp=$(mktemp)
cut -d "$(printf '\t')" -f 3 "$mpvtmp" >"$rectmp"
# Get list
cut -d "$(printf '\t')" -f 2- "$mpvtmp" |
awk \
-F "\t" \
-v file_local_recordings="${rectmp:-}" \
-v format="$REC_FORMAT_NO_NUMBER" \
-v format_current="$FORMAT_CURRENT" \
-v current_id="$current_id" \
"$AWK_RECORDINGS" |
cut -d "$(printf '\t')" -f 2- |
column -t -s "$(printf '\t')" -R 5 |
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2\t\3|'
rm -f "$rectmp" "$mpvtmp"
} }

View File

@@ -225,6 +225,7 @@ __precompute_lists() {
.id, .id,
.type, .type,
.name, .name,
."sort-name",
.disambiguation, .disambiguation,
.["life-span"].begin, .["life-span"].begin,
.["life-span"].end .["life-span"].end
@@ -246,47 +247,8 @@ __precompute_lists() {
# The resulting views are stored in the files `LOCALDATA_ARTISTS_VIEW` and # The resulting views are stored in the files `LOCALDATA_ARTISTS_VIEW` and
# `LOCALDATA_RELEASEGROUPS_VIEW`. # `LOCALDATA_RELEASEGROUPS_VIEW`.
precompute_views() { precompute_views() {
awk \ awk_artists "$SORT_ARTIST_DEFAULT" <"$LOCALDATA_ARTISTS_LIST" >"$LOCALDATA_ARTISTS_VIEW"
-F "\t" \ awk_releasegroups "$SORT_RG_DEFAULT" <"$LOCALDATA_RELEASEGROUPS_LIST" >"$LOCALDATA_RELEASEGROUPS_VIEW"
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
-v format_person="$AV_PERSON" \
-v format_group="$AV_GROUP" \
-v format_disambiguation="$AV_DISAMBIGUATION" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_ARTISTS" "$LOCALDATA_ARTISTS_LIST" |
sort |
column -t -s "$(printf '\t')" -l 2 >"$LOCALDATA_ARTISTS_VIEW"
#column -t -s "$(printf '\t')" |
#sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_ARTISTS_VIEW"
awk \
-F "\t" \
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
-v format_release="$RGV_RELEASE" \
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
-v format_year="$RGV_YEAR" \
-v format_album="$FORMAT_TYPE_ALBUM" \
-v format_single="$FORMAT_TYPE_SINGLE" \
-v format_ep="$FORMAT_TYPE_EP" \
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
-v format_other="$FORMAT_TYPE_OTHER" \
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_RELEASEGROUPS" "$LOCALDATA_RELEASEGROUPS_LIST" | sort -n -r |
cut -d "$(printf '\t')" -f 2- |
column -t -s "$(printf '\t')" -l 5 >"$LOCALDATA_RELEASEGROUPS_VIEW"
#column -t -s "$(printf '\t')" | #column -t -s "$(printf '\t')" |
#sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_RELEASEGROUPS_VIEW" #sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_RELEASEGROUPS_VIEW"
} }

View File

@@ -180,8 +180,7 @@ mb_results_async() {
sleep 1 sleep 1
done done
# Show results # Show results
column -t -s "$(printf '\t')" "$RESULTS" | cat "$RESULTS" || true
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|'
} }
# Initiate search on MusicBrainz # Initiate search on MusicBrainz
@@ -200,30 +199,29 @@ mb_search_async() {
rm -f "$PIDFILE" rm -f "$PIDFILE"
kill -9 "$pid" >/dev/null 2>&1 || true kill -9 "$pid" >/dev/null 2>&1 || true
fi fi
# Stop, if no search string is given # Clear search and stop if no search string is given
[ "$FZF_QUERY" ] || exit 0 if [ ! "$FZF_QUERY" ]; then
rm -f "$RESULTS"
touch "$RESULTS"
exit 0
fi
# Store PID of current process # Store PID of current process
echo "$$" >"$PIDFILE" echo "$$" >"$PIDFILE"
touch "$LOCKFILE" touch "$LOCKFILE"
sleep 1 sleep 1
if [ "$view" = "$VIEW_SEARCH_ARTIST" ]; then if [ "$view" = "$VIEW_SEARCH_ARTIST" ]; then
info "search artist. results: $RESULTS"
api_mb_search_artist "$FZF_QUERY" | api_mb_search_artist "$FZF_QUERY" |
$JQ '.artists[] | [ $JQ '.artists[] | [
.id, .id,
.type, .type,
.name, .name,
."sort-name",
.disambiguation, .disambiguation,
.["life-span"].begin, .["life-span"].begin,
.["life-span"].end .["life-span"].end
] | join("\t")' | ] | join("\t")' |
awk \ awk_artists "$SORT_NO" >"$RESULTS" ||
-F "\t" \
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
-v format_person="$AV_PERSON" \
-v format_group="$AV_GROUP" \
-v format_disambiguation="$AV_DISAMBIGUATION" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_ARTISTS" >"$RESULTS" ||
true true
else else
api_mb_search_releasegroup "$FZF_QUERY" | api_mb_search_releasegroup "$FZF_QUERY" |
@@ -235,34 +233,7 @@ mb_search_async() {
.title, .title,
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")) (."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
] | join("\t")' | ] | join("\t")' |
awk \ awk_releasegroups "$SORT_NO" >"$RESULTS" ||
-F "\t" \
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
-v format_release="$RGV_RELEASE" \
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
-v format_year="$RGV_YEAR" \
-v format_album="$FORMAT_TYPE_ALBUM" \
-v format_single="$FORMAT_TYPE_SINGLE" \
-v format_ep="$FORMAT_TYPE_EP" \
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
-v format_other="$FORMAT_TYPE_OTHER" \
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
-v format_local="$FORMAT_LOCAL" \
"$AWK_RELEASEGROUPS" |
cut -d "$(printf '\t')" -f 2- >"$RESULTS" ||
true true
fi fi
# Process ends now: Display and quit # Process ends now: Display and quit

View File

@@ -50,7 +50,7 @@ mpv_playlist_position() {
# Moves the track at the first index to the position of the track of the second # Moves the track at the first index to the position of the track of the second
# index. Also here, indices are 0 based. # index. Also here, indices are 0 based.
mpv_playlist_move() { mpv_playlist_move() {
__mpv_command_with_args2 "playlist-move" "$1" "$2" >>/tmp/foo __mpv_command_with_args2 "playlist-move" "$1" "$2"
} }
# Remove all tracks from the playlist # Remove all tracks from the playlist

View File

@@ -99,6 +99,7 @@ __generate_playlist() {
# pressed is stored in the environment variable FZF_KEY and is resolved to # pressed is stored in the environment variable FZF_KEY and is resolved to
# the playback command through the method `__playback_cmd_from_key`. # the playback command through the method `__playback_cmd_from_key`.
playback() { playback() {
info "call to playback: $*"
view=${1:-} view=${1:-}
mbid_current="${2:-}" mbid_current="${2:-}"
mbid="${3:-}" mbid="${3:-}"
@@ -107,6 +108,7 @@ playback() {
case "$pbcmd" in case "$pbcmd" in
"$PLAYBACK_CMD_PLAY") "$PLAYBACK_CMD_PLAY")
[ "$path" ] || exit 0 [ "$path" ] || exit 0
info "play pressed"
case "$view" in case "$view" in
"$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;; "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;;
"$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null ;; "$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null ;;

44
src/sh/sort.sh Normal file
View File

@@ -0,0 +1,44 @@
# Sort methods for generated lists
if [ ! "${SORT_LOADED:-}" ]; then
# Sort specifications
#
# - No sort
# - Alphabetic sort
# - Numeric sort
SORT_NO="no-sort"
SORT_ALPHA="sort-alpha"
SORT_NUMERIC="sort-numeric"
# Artists may be sorted according to the name or the sort-name taken from
# MusicBrainz
SORT_ARTIST="sort-artist"
SORT_ARTIST_SORTNAME="sort-artist-sortname"
# Release-groups may be sorted according to the release year or the title
SORT_RG_TITLE="sort-rg-title"
SORT_RG_YEAR="sort-rg-year"
export SORT_NO SORT_ALPHA SORT_NUMERIC SORT_ARTIST SORT_ARTIST_SORTNAME \
SORT_RG_TITLE SORT_RG_YEAR
# Configurable default sort
SORT_ARTIST_DEFAULT="${SORT_ARTIST_DEFAULT:-"$SORT_ARTIST"}"
SORT_RG_DEFAULT="${SORT_RG_DEFAULT:-"$SORT_RG_YEAR"}"
export SORT_ARTIST_DEFAULT SORT_RG_DEFAULT
export SORT_LOADED=1
fi
# Sorting switches
#
# @argument $1: Sort specification (may be one of SORT_NO, SORT_ALPHA,
# SORT_NUMERIC)
#
# This method sorts the stream read from stdin.
sort_list() {
case "${1:-}" in
"$SORT_ALPHA") cat | sort -t "$(printf '\t')" -k 2,2 ;;
"$SORT_NUMERIC") cat | sort -t "$(printf '\t')" -k 2,2 -n ;;
*) cat ;;
esac
}

View File

@@ -4,165 +4,327 @@
# #
# This theme requires fonts that support utf-8, colors, and emojis. # This theme requires fonts that support utf-8, colors, and emojis.
# Colors (internal only) if [ ! "${THEME_LOADED:-}" ]; then
ESC=$(printf '\033') # Colors (internal only)
BOLD="${ESC}[1m" ESC=$(printf '\033')
FAINT="${ESC}[2m" BOLD="${ESC}[1m"
UNDERLINE="${ESC}[4m" FAINT="${ESC}[2m"
CARTIST="${ESC}[38;5;209m" UNDERLINE="${ESC}[4m"
CTITLE="${ESC}[38;5;229m" CARTIST="${ESC}[38;5;209m"
CRELINFO="${ESC}[38;5;179m" CTITLE="${ESC}[38;5;229m"
CYEAR="${ESC}[38;5;179m" CRELINFO="${ESC}[38;5;179m"
CDISAMB="$FAINT${ESC}[38;5;172m" CYEAR="${ESC}[38;5;179m"
CNOTE="${ESC}[38;5;242m" CDISAMB="$FAINT${ESC}[38;5;172m"
CXXX="${ESC}[38;5;109m" CNOTE="${ESC}[38;5;242m"
CDESC="${ESC}[38;5;254m" CXXX="${ESC}[38;5;109m"
CLIFE="${ESC}[38;5;251m" CDESC="${ESC}[38;5;254m"
CKB="${ESC}[38;5;224m" CLIFE="${ESC}[38;5;251m"
OFF="${ESC}[m" CKB="${ESC}[38;5;224m"
OFF="${ESC}[m"
# Pointers # Pointers
# ======== # ========
# Sign that indicates the existence of audio files # Sign that indicates the existence of audio files
FORMAT_LOCAL="${FORMAT_LOCAL:-"🔆"}" FORMAT_LOCAL="${FORMAT_LOCAL:-"🔆"}"
# Pointer to the track currently playing (playlist) export FORMAT_LOCAL
FORMAT_CURRENT="${FORMAT_CURRENT:-"👉"}"
export FORMAT_LOCAL FORMAT_CURRENT
# Input prompt # Input prompt
# ============= # =============
# Search prompt # General search prompt (for now only used when choosing one-of-many artist)
SEARCH_PROMPT=${SEARCH_PROMPT:-"🔎 〉"} SEARCH_PROMPT=${SEARCH_PROMPT:-"🔎 〉"}
export SEARCH_PROMPT export SEARCH_PROMPT
# Headers # General workings of format strings
# ======= #
# Header that displays artist's name # A format string (_FMT) contains placeholders, e.g., <<name>>. These
HEADER_ARTIST="${HEADER_ARTIST:-"🎤 ${CARTIST}%s$OFF"}" # placeholders are filled with the relevant information. A placeholder may
# Header that displays the release-group name after artist's # occur zero times, once, or more than once. There are two types of
HEADER_ARTIST_RELEASEGROUP="${HEADER_ARTIST_RELEASEGROUP:-"🎤 ${CARTIST}%s$OFF${CTITLE}%s$OFF"}" # placeholders: strings and items. A placeholder of type string comes with a
# Header that in addition to `HEADER_ARTIST_RELEASEGROUP` also shows some # variable containing a `printf` expression (_FMT_placeholder). This `printf`
# release information # expression may be used to additionally modify the string passed. If the
HEADER_RELEASE="${HEADER_RELEASE:-"🎤 ${CARTIST}%s$OFF${CTITLE}%s$OFF 〉%s"}" # string passed is empty, then each corresponding placeholder is replaced
# The release information is formatted as follows (placeholders implicit): # with the empty string, i.e., the `printf` expression is bypassed. A
HEADER_RELEASE_FORMAT="${HEADER_RELEASE_FORMAT:-"${CRELINFO}<<tracks>> tx <<media>> $OFF|$CRELINFO <<label>> <<country>> <<year>>$OFF"}" # placeholder of the alternative type (item) comes with a series of variables
export HEADER_ARTIST HEADER_ARTIST_RELEASEGROUP HEADER_RELEASE HEADER_RELEASE_FORMAT # that encode constants to be used (_FMT_placeholder_XYZ).
#
# The items in the format string may be separated with "\t". This will induce
# a proper representation (using `column`). By default, all fields but the
# first are left aligned, and the first field is right aligned. This can be
# changed by setting the appropriate FMT_RIGHTALIGN variable. If that
# variable is empty, then the first field is right aligned. This means that
# at least one field must be right aligned.
#
# Artist view
# ===========
# <<flag>> item Indication for locally available audio files
# <<type>> item Indicator for single-person artist or group
# <<name>> string Artist name
# <<disambiguation>> string Disambiguation string
#
AV_FMT="${AV_FMT:-"<<flag>>\t<<type>> <<name>> <<disambiguation>>"}"
AV_FMT_CNT=$(($(printf "$AV_FMT" | tr -cd '\t' | wc -c) + 1))
AV_FMT_RIGHTALIGN="${AV_FMT_RIGHTALIGN:-"1"}"
AV_FMT_FLAG_LOCAL="${AV_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}"
AV_FMT_FLAG_NO_LOCAL="${AV_FMT_FLAG_NO_LOCAL:-""}"
AV_FMT_TYPE_PERSON="${AV_FMT_TYPE_PERSON:-🧑‍🎤}"
AV_FMT_TYPE_GROUP="${AV_FMT_TYPE_GROUP:-🧑‍🤝‍🧑}"
AV_FMT_NAME="${AV_FMT_NAME:-"${CARTIST}%s$OFF"}"
AV_FMT_DISAMBIGUATION="${AV_FMT_DISAMBIGUATION:-"${CDISAMB}(%s)$OFF"}"
export AV_FMT AV_FMT_CNT AV_FMT_RIGHTALIGN AV_FMT_FLAG_LOCAL \
AV_FMT_FLAG_NO_LOCAL AV_FMT_TYPE_PERSON AV_FMT_TYPE_GROUP AV_FMT_NAME \
AV_FMT_DISAMBIGUATION
# Artist view # Release-group view
# =========== # ==================
# Artist string for persons # <<flag>> item Indication for locally available audio files
AV_PERSON="${AV_PERSON:-"🧑‍🎤 $CARTIST<<name>>$OFF"}" # <<type>> item Indicates the type
# Artist string for groups # <<hassecondary>> item Indicates if there is some secondary type or none
AV_GROUP="${AV_GROUP:-"🧑‍🤝‍🧑 $CARTIST<<name>>$OFF"}" # <<secondary>> string List of secondary types
# Artist disambiguation string # <<title>> string Title of album
AV_DISAMBIGUATION="${AV_DISAMBIGUATION:-"$CDISAMB(<<disambiguation>>)$OFF"}" # <<artist>> string Artist of album
export AV_PERSON AV_GROUP AV_DISAMBIGUATION # <<year>> string Year of initial release
# TODO: The above <<secondary>> is of a joint item-string type; unify or document.
RGV_FMT="${RGV_FMT:-"<<flag>>\t<<type>>\t<<hassecondary>>\t<<title>><<artist>> <<year>> <<secondary>>"}"
RGV_FMT_CNT=$(($(printf "$RGV_FMT" | tr -cd '\t' | wc -c) + 1))
RGV_FMT_RIGHTALIGN="${RGV_FMT_RIGHTALIGN:-"1"}"
RGV_FMT_FLAG_LOCAL="${RGV_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}"
RGV_FMT_FLAG_NO_LOCAL="${RGV_FMT_FLAG_NO_LOCAL:-""}"
RGV_FMT_TYPE_SINGLE="${RGV_FMT_TYPE_SINGLE:-"SI 🎶"}"
RGV_FMT_TYPE_ALBUM="${RGV_FMT_TYPE_ALBUM:-"LP 💽"}"
RGV_FMT_TYPE_EP="${RGV_FMT_TYPE_EP:-"EP 📀"}"
RGV_FMT_TYPE_BROADCAST="${RGV_FMT_TYPE_BROADCAST:-"BR 📻"}"
RGV_FMT_TYPE_OTHER="${RGV_FMT_TYPE_OTHER:-"OT ❔"}"
RGV_FMT_TYPE_UNKNOWN="${RGV_FMT_TYPE_UNKNOWN:-""}"
RGV_FMT_HASSECONDARY_YES="${RGV_FMT_HASSECONDARY_YES:-"☼"}"
RGV_FMT_HASSECONDARY_NO="${RGV_FMT_HASSECONDARY_NO:-""}"
RGV_FMT_SECONDARY="${RGV_FMT_SECONDARY:-"${CNOTE}[☼: %s]$OFF"}"
RGV_FMT_SECONDARY_SOUNDTRACK="${RGV_FMT_SECONDARY_SOUNDTRACK:-"🎬 soundtrack"}"
RGV_FMT_SECONDARY_SPOKENWORD="${RGV_FMT_SECONDARY_SPOKENWORD:-"📖 spokenword"}"
RGV_FMT_SECONDARY_INTERVIEW="${RGV_FMT_SECONDARY_INTERVIEW:-"💬 interview"}"
RGV_FMT_SECONDARY_AUDIOBOOK="${RGV_FMT_SECONDARY_AUDIOBOOK:-"🎧 audiobook"}"
RGV_FMT_SECONDARY_AUDIODRAMA="${RGV_FMT_SECONDARY_AUDIODRAMA:-"🎭 audio drama"}"
RGV_FMT_SECONDARY_LIVE="${RGV_FMT_SECONDARY_LIVE:-"🎤 live"}"
RGV_FMT_SECONDARY_REMIX="${RGV_FMT_SECONDARY_REMIX:-"🔁 remix"}"
RGV_FMT_SECONDARY_DJMIX="${RGV_FMT_SECONDARY_DJMIX:-"🪩 DJ-mix"}"
RGV_FMT_SECONDARY_MIXTAPE="${RGV_FMT_SECONDARY_MIXTAPE:-"📼 mixtape"}"
RGV_FMT_SECONDARY_DEMO="${RGV_FMT_SECONDARY_DEMO:-"🧪 demo"}"
RGV_FMT_SECONDARY_FIELDREC="${RGV_FMT_SECONDARY_FIELDREC:-"🌿 field recording"}"
RGV_FMT_TITLE="${RGV_FMT_TITLE:-"${CTITLE}%s$OFF"}"
RGV_FMT_ARTIST="${RGV_FMT_ARTIST:-"${CARTIST}%s$OFF"}"
RGV_FMT_YEAR="${RGV_FMT_YEAR:-"${CYEAR}(%s)$OFF"}"
export RGV_FMT RGV_FMT_CNT RGV_FMT_RIGHTALIGN RGV_FMT_FLAG_LOCAL \
RGV_FMT_FLAG_NO_LOCAL RGV_FMT_TYPE_SINGLE RGV_FMT_TYPE_ALBUM \
RGV_FMT_TYPE_EP RGV_FMT_TYPE_BROADCAST RGV_FMT_TYPE_OTHER \
RGV_FMT_TYPE_UNKNOWN RGV_FMT_HASSECONDARY_YES RGV_FMT_HASSECONDARY_NO \
RGV_FMT_SECONDARY RGV_FMT_SECONDARY_SOUNDTRACK \
RGV_FMT_SECONDARY_SPOKENWORD RGV_FMT_SECONDARY_INTERVIEW \
RGV_FMT_SECONDARY_AUDIOBOOK RGV_FMT_SECONDARY_AUDIODRAMA \
RGV_FMT_SECONDARY_LIVE RGV_FMT_SECONDARY_REMIX RGV_FMT_SECONDARY_DJMIX \
RGV_FMT_SECONDARY_MIXTAPE RGV_FMT_SECONDARY_DEMO \
RGV_FMT_SECONDARY_FIELDREC RGV_FMT_TITLE RGV_FMT_ARTIST RGV_FMT_YEAR
# Release-group view # Release view
# ================== # ============
# Default release group string # <<flag>> item Indication for locally available audio files
RGV_RELEASE="${RGV_RELEASE:-"${CTITLE}<<title>>$OFF"}" # <<status>> item Release status
# Release group string if the artist name differs from the current artist # <<tracks>> string Total number of track
RGV_RELEASE_W_ARTIST="${RGV_RELEASE_W_ARTIST:-"${CTITLE}<<title>>$OFF${CARTIST}<<artist>>$OFF"}" # <<media>> string Media description
# Year of the release group # <<year>> string Release year
RGV_YEAR="${RGV_YEAR:-"${CYEAR}(<<year>>)$OFF"}" # <<country>> string Release country
export RGV_RELEASE RGV_RELEASE_W_ARTIST RGV_YEAR # <<label>> string Release label
# <<title>> string Optional titel string
# <<artist>> string Optional artist string
RV_FMT="${RV_FMT:-"<<flag>>\t<<status>>\t<<tracks>>\t<<media>>\t<<year>>\t<<country>>\t<<label>>\t<<title>> <<artist>>"}"
RV_FMT_CNT=$(($(printf "$RV_FMT" | tr -cd '\t' | wc -c) + 1))
RV_FMT_RIGHTALIGN="${RV_FMT_RIGHTALIGN:-"1,3"}"
RV_FMT_FLAG_LOCAL="${RV_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}"
RV_FMT_FLAG_NO_LOCAL="${RV_FMT_FLAG_NO_LOCAL:-""}"
RV_FMT_STATUS_OFFICIAL="${RV_FMT_STATUS_OFFICIAL:-"🟢"}"
RV_FMT_STATUS_PROMO="${RV_FMT_STATUS_PROMO:-"📣"}"
RV_FMT_STATUS_BOOTLEG="${RV_FMT_STATUS_BOOTLEG:-"💣"}"
RV_FMT_STATUS_PSEUDO="${RV_FMT_STATUS_PSEUDO:-"🌀"}"
RV_FMT_STATUS_WITHDRAWN="${RV_FMT_STATUS_WITHDRAWN:-"🔙"}"
RV_FMT_STATUS_EXPUNGED="${RV_FMT_STATUS_EXPUNGED:-"🧹"}"
RV_FMT_STATUS_CANCELLED="${RV_FMT_STATUS_CANCELLED:-"❌"}"
RV_FMT_STATUS_UNKNOWN="${RV_FMT_STATUS_UNKNOWN:-""}"
RV_FMT_TRACKS="${RV_FMT_TRACKS:-"${CXXX}%s tracks$OFF"}"
RV_FMT_MEDIA="${RV_FMT_MEDIA:-"${CXXX}%s$OFF"}"
RV_FMT_YEAR="${RV_FMT_YEAR:-"${CYEAR}%s$OFF"}"
RV_FMT_COUNTRY="${RV_FMT_COUNTRY:-"${CYEAR}%s$OFF"}"
RV_FMT_LABEL="${RV_FMT_LABEL:-"${CARTIST}%s$OFF"}"
RV_FMT_TITLE="${RV_FMT_TITLE:-"${FAINT}as$OFF ${CTITLE}%s$OFF"}"
RV_FMT_ARTIST="${RV_FMT_ARTIST:-"${FAINT}by$OFF ${CTITLE}%s$OFF"}"
export RV_FMT RV_FMT_CNT RV_FMT_RIGHTALIGN RV_FMT_FLAG_LOCAL \
RV_FMT_FLAG_NO_LOCAL RV_FMT_STATUS_OFFICIAL RV_FMT_STATUS_PROMO \
RV_FMT_STATUS_BOOTLEG RV_FMT_STATUS_PSEUDO RV_FMT_STATUS_WITHDRAWN \
RV_FMT_STATUS_EXPUNGED RV_FMT_STATUS_CANCELLED RV_FMT_STATUS_UNKNOWN \
RV_FMT_TRACKS RV_FMT_MEDIA RV_FMT_YEAR RV_FMT_COUNTRY RV_FMT_LABEL \
RV_FMT_TITLE RV_FMT_ARTIST
# Release-group types # Recording view
# =================== # ==============
# Album # <<flag>> item Indication for locally available audio files
FORMAT_TYPE_ALBUM="${FORMAT_TYPE_ALBUM:-"LP 💽"}" # <<media>> string Media identifier
# EP # <<nr>> string Track number within media
FORMAT_TYPE_EP="${FORMAT_TYPE_EP:-"EP 📀"}" # <<title>> string Track title
# Single # <<artist>> string Track artist
FORMAT_TYPE_SINGLE="${FORMAT_TYPE_SINGLE:-"SI 🎶"}" # <<duration>> string Track duration
# Broadcast REC_FMT="${REC_FMT:-"<<flag>>\t<<media>>\t<<nr>>\t<<title>>\t<<artist>>\t<<duration>>"}"
FORMAT_TYPE_BROADCAST="${FORMAT_TYPE_BROADCAST:-"BR 📻"}" REC_FMT_CNT=$(($(printf "$REC_FMT" | tr -cd '\t' | wc -c) + 1))
# Other REC_FMT_RIGHTALIGN="${REC_FMT_RIGHTALIGN:-"1,2,3,6"}"
FORMAT_TYPE_OTHER="${FORMAT_TYPE_OTHER:-"OT ❔"}" REC_FMT_FLAG_LOCAL="${REC_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}"
# Flag to indicate that the given release group has associated secondary types. REC_FMT_FLAG_NO_LOCAL="${REC_FMT_FLAG_NO_LOCAL:-""}"
FORMAT_TYPE_HAS_SECONDARY="${FORMAT_TYPE_HAS_SECONDARY:-"%s☼"}" REC_FMT_MEDIA="${REC_FMT_MEDIA:-"${CNOTE}${FAINT}%s$OFF"}"
# Style to represent secondary types (takes one %s placeholder) REC_FMT_NR="${REC_FMT_NR:-"${CNOTE}%s$OFF"}"
FORMAT_TYPE_SECONDARY="${FORMAT_TYPE_SECONDARY:-"${CNOTE}[☼: %s]$OFF"}" REC_FMT_TITLE="${REC_FMT_TITLE:-"${CTITLE}%s$OFF"}"
# Secondary types REC_FMT_ARTIST="${REC_FMT_ARTIST:-"${CARTIST}%s$OFF"}"
FORMAT_TYPE_SECONDARY_COMPILATION="${FORMAT_TYPE_SECONDARY_COMPILATION:-"🧩 compilation"}" REC_FMT_DURATION="${REC_FMT_DURATION:-"${CXXX}%s$OFF"}"
FORMAT_TYPE_SECONDARY_SOUNDTRACK="${FORMAT_TYPE_SECONDARY_SOUNDTRACK:-"🎬 soundtrack"}" export REC_FMT REC_FMT_CNT REC_FMT_RIGHTALIGN REC_FMT_FLAG_LOCAL \
FORMAT_TYPE_SECONDARY_SPOKENWORD="${FORMAT_TYPE_SECONDARY_SPOKENWORD:-"📖 spokenword"}" REC_FMT_FLAG_NO_LOCAL REC_FMT_MEDIA REC_FMT_NR REC_FMT_TITLE \
FORMAT_TYPE_SECONDARY_INTERVIEW="${FORMAT_TYPE_SECONDARY_INTERVIEW:-"💬 interview"}" REC_FMT_ARTIST REC_FMT_DURATION
FORMAT_TYPE_SECONDARY_AUDIOBOOK="${FORMAT_TYPE_SECONDARY_AUDIOBOOK:-"🎧 audiobook"}"
FORMAT_TYPE_SECONDARY_AUDIODRAMA="${FORMAT_TYPE_SECONDARY_AUDIODRAMA:-"🎭 audio drama"}"
FORMAT_TYPE_SECONDARY_LIVE="${FORMAT_TYPE_SECONDARY_LIVE:-"🎤 live"}"
FORMAT_TYPE_SECONDARY_REMIX="${FORMAT_TYPE_SECONDARY_REMIX:-"🔁 remix"}"
FORMAT_TYPE_SECONDARY_DJMIX="${FORMAT_TYPE_SECONDARY_DJMIX:-"🪩 DJ-mix"}"
FORMAT_TYPE_SECONDARY_MIXTAPE="${FORMAT_TYPE_SECONDARY_MIXTAPE:-"📼 mixtape"}"
FORMAT_TYPE_SECONDARY_DEMO="${FORMAT_TYPE_SECONDARY_DEMO:-"🧪 demo"}"
FORMAT_TYPE_SECONDARY_FIELDREC="${FORMAT_TYPE_SECONDARY_FIELDREC:-"🌿 field recording"}"
export FORMAT_TYPE_ALBUM FORMAT_TYPE_EP FORMAT_TYPE_SINGLE \
FORMAT_TYPE_BROADCAST FORMAT_TYPE_OTHER FORMAT_TYPE_HAS_SECONDARY \
FORMAT_TYPE_SECONDARY FORMAT_TYPE_SECONDARY_COMPILATION \
FORMAT_TYPE_SECONDARY_SOUNDTRACK FORMAT_TYPE_SECONDARY_SPOKENWORD \
FORMAT_TYPE_SECONDARY_INTERVIEW FORMAT_TYPE_SECONDARY_AUDIOBOOK \
FORMAT_TYPE_SECONDARY_AUDIODRAMA FORMAT_TYPE_SECONDARY_LIVE \
FORMAT_TYPE_SECONDARY_REMIX FORMAT_TYPE_SECONDARY_DJMIX \
FORMAT_TYPE_SECONDARY_MIXTAPE FORMAT_TYPE_SECONDARY_DEMO \
FORMAT_TYPE_SECONDARY_FIELDREC
# Artist Preview # Recording view (playlist)
# ============== # =========================
# Main preview format. Takes two %s placeholder. The first is for the artist # <<playing>> item Mark for currently playing track
# biography. The second for the life span. # <<title>> string Track title
APV_FORMAT="${APV_FORMAT:-"\n\n${CDESC}%s${OFF}\n\n${CLIFE}%s${OFF}"}" # <<artist>> string Track artist
# Specification of a date # <<duration>> string Track duration
APV_DATE="${APV_DATE:-"%s"}" PLYLST_FMT="${PLYLST_FMT:-"<<playing>>\t<<title>>\t<<artist>>\t<<duration>>"}"
# Specification of a place PLYLST_FMT_CNT=$(($(printf "$PLYLST_FMT" | tr -cd '\t' | wc -c) + 1))
APV_PLACE="${APV_PLACE:-"%s"}" PLYLST_FMT_RIGHTALIGN="${PLYLST_FMT_RIGHTALIGN:-"1"}"
# Specification of a date and a place (in that order) PLYLST_FMT_PLAYING_YES="${PLYLST_FMT_PLAYING_YES:-"👉"}"
APV_DATEPLACE="${APV_DATEPLACE:-"$APV_DATE, $APV_PLACE"}" PLYLST_FMT_PLAYING_NO="${PLYLST_FMT_PLAYING_NO:-""}"
# String to represent when/where a person is born PLYLST_FMT_TITLE="${PLYLST_FMT_TITLE:-"${CTITLE}%s$OFF"}"
APV_BORN="${APV_BORN:-"🍼 Born: %s"}" PLYLST_FMT_ARTIST="${PLYLST_FMT_ARTIST:-"${CARTIST}%s$OFF"}"
# String to represent when/where a person died PLYLST_FMT_DURATION="${PLYLST_FMT_DURATION:-"${CXXX}%s$OFF"}"
APV_DIED="${APV_DIED:-"🕯️ Died: %s"}" export PLYLST_FMT PLYLST_FMT_CNT PLYLST_FMT_RIGHTALIGN \
export APV_FORMAT APV_DATE APV_PLACE APV_DATEPLACE APV_BORN APV_DIED PLYLST_FMT_PLAYING_YES PLYLST_FMT_PLAYING_NO PLYLST_FMT_TITLE \
PLYLST_FMT_ARTIST PLYLST_FMT_DURATION
# Release view # Headers
# ============ # =======
# Format of a string that represents a release. # These header strings are based on the respective view and its fields
RV_FORMAT="${RV_FORMAT:-"<<status>>\t${CXXX}<<tracks>> tracks\t<<media>>$OFF\t${CYEAR}<<year>>\t<<country>>$OFF\t${CARTIST}<<label>>$OFF"}" # defined above.
# Additional string to display the release title and artist name #
RV_TITLE_ARTIST="${RV_TITLE_ARTIST:-"${FAINT}as ${CTITLE}<<title>>$OFF by ${FAINT}${CARTIST}<<artist>>$OFF"}" # Header that displays artist's name (based on artist view)
# Additional string to display the release title HEADER_ARTIST="${HEADER_ARTIST:-" ${CARTIST}%s$OFF "}"
RV_TITLE="${RV_TITLE:-"${FAINT}as ${CTITLE}<<title>>$OFF"}" HEADER_ARTIST_FMT="${HEADER_ARTIST_FMT:-"🎤\t<<name>> 〉"}"
# Additional string to display the artist HEADER_ARTIST_FMT_CNT=$(($(printf "$HEADER_ARTIST_FMT" | tr -cd '\t' | wc -c) + 1))
RV_ARTIST="${RV_ARTIST:-"${FAINT}by ${CARTIST}<<artist>>$OFF"}" HEADER_ARTIST_FMT_RIGHTALIGN="${HEADER_ARTIST_FMT_RIGHTALIGN:-"1"}"
export RV_FORMAT RV_TITLE_ARTIST RV_TITLE RV_ARTIST HEADER_ARTIST_FMT_FLAG_LOCAL="${HEADER_ARTIST_FMT_FLAG_LOCAL:-"$AV_FMT_FLAG_LOCAL"}"
HEADER_ARTIST_FMT_FLAG_NO_LOCAL="${HEADER_ARTIST_FMT_FLAG_NO_LOCAL:-"$AV_FMT_FLAG_NO_LOCAL"}"
HEADER_ARTIST_FMT_TYPE_PERSON="${HEADER_ARTIST_FMT_TYPE_PERSON:-"$AV_FMT_TYPE_PERSON"}"
HEADER_ARTIST_FMT_TYPE_GROUP="${HEADER_ARTIST_FMT_TYPE_GROUP:-"$AV_FMT_TYPE_GROUP"}"
HEADER_ARTIST_FMT_NAME="${HEADER_ARTIST_FMT_NAME:-"$AV_FMT_NAME"}"
HEADER_ARTIST_FMT_DISAMBIGUATION="${HEADER_ARTIST_FMT_DISAMBIGUATION:-"$AV_FMT_DISAMBIGUATION"}"
export HEADER_ARTIST HEADER_ARTIST_FMT HEADER_ARTIST_FMT_CNT \
HEADER_ARTIST_FMT_RIGHTALIGN HEADER_ARTIST_FMT_FLAG_LOCAL \
HEADER_ARTIST_FMT_FLAG_NO_LOCAL HEADER_ARTIST_FMT_TYPE_PERSON \
HEADER_ARTIST_FMT_TYPE_GROUP HEADER_ARTIST_FMT_NAME \
HEADER_ARTIST_FMT_DISAMBIGUATION
# Release Status # Header that displays the release-group (based on release-group view)
# ============== HEADER_RG_FMT="${HEADER_RG_FMT:-"🎤\t<<artist>> 》<<title>> 〉"}"
FORMAT_STATUS_OFFICIAL="${FORMAT_STATUS_OFFICIAL:-"🟢"}" HEADER_RG_FMT_CNT=$(($(printf "$HEADER_RG_FMT" | tr -cd '\t' | wc -c) + 1))
FORMAT_STATUS_PROMO="${FORMAT_STATUS_PROMO:-"📣"}" HEADER_RG_FMT_RIGHTALIGN="${HEADER_RG_FMT_RIGHTALIGN:-"1"}"
FORMAT_STATUS_BOOTLEG="${FORMAT_STATUS_BOOTLEG:-"💣"}" HEADER_RG_FMT_FLAG_LOCAL="${HEADER_RG_FMT_FLAG_LOCAL:-"$RGV_FMT_FLAG_LOCAL"}"
FORMAT_STATUS_PSEUDO="${FORMAT_STATUS_PSEUDO:-"🌀"}" HEADER_RG_FMT_FLAG_NO_LOCAL="${HEADER_RG_FMT_FLAG_NO_LOCAL:-"$RGV_FMT_FLAG_NO_LOCAL"}"
FORMAT_STATUS_WITHDRAWN="${FORMAT_STATUS_WITHDRAWN:-"🔙"}" HEADER_RG_FMT_TYPE_SINGLE="${HEADER_RG_FMT_TYPE_SINGLE:-"$RGV_FMT_TYPE_SINGLE"}"
FORMAT_STATUS_EXPUNGED="${FORMAT_STATUS_EXPUNGED:-"🧹"}" HEADER_RG_FMT_TYPE_ALBUM="${HEADER_RG_FMT_TYPE_ALBUM:-"$RGV_FMT_TYPE_ALBUM"}"
FORMAT_STATUS_CANCELLED="${FORMAT_STATUS_CANCELLED:-"❌"}" HEADER_RG_FMT_TYPE_EP="${HEADER_RG_FMT_TYPE_EP:-"$RGV_FMT_TYPE_EP"}"
export FORMAT_STATUS_OFFICIAL FORMAT_STATUS_PROMO FORMAT_STATUS_BOOTLEG \ HEADER_RG_FMT_TYPE_BROADCAST="${HEADER_RG_FMT_TYPE_BROADCAST:-"$RGV_FMT_TYPE_BROADCAST"}"
FORMAT_STATUS_PSEUDO FORMAT_STATUS_WITHDRAWN FORMAT_STATUS_EXPUNGED \ HEADER_RG_FMT_TYPE_OTHER="${HEADER_RG_FMT_TYPE_OTHER:-"$RGV_FMT_TYPE_OTHER"}"
FORMAT_STATUS_CANCELLED HEADER_RG_FMT_TYPE_UNKNOWN="${HEADER_RG_FMT_TYPE_UNKNOWN:-"$RGV_FMT_TYPE_UNKNOWN"}"
HEADER_RG_FMT_HASSECONDARY_YES="${HEADER_RG_FMT_HASSECONDARY_YES:-"$RGV_FMT_HASSECONDARY_YES"}"
HEADER_RG_FMT_HASSECONDARY_NO="${HEADER_RG_FMT_HASSECONDARY_NO:-"$RGV_FMT_HASSECONDARY_NO"}"
HEADER_RG_FMT_SECONDARY="${HEADER_RG_FMT_SECONDARY:-"$RGV_FMT_SECONDARY"}"
HEADER_RG_FMT_SECONDARY_SOUNDTRACK="${HEADER_RG_FMT_SECONDARY_SOUNDTRACK:-"$RGV_FMT_SECONDARY_SOUNDTRACK"}"
HEADER_RG_FMT_SECONDARY_SPOKENWORD="${HEADER_RG_FMT_SECONDARY_SPOKENWORD:-"$RGV_FMT_SECONDARY_SPOKENWORD"}"
HEADER_RG_FMT_SECONDARY_INTERVIEW="${HEADER_RG_FMT_SECONDARY_INTERVIEW:-"$RGV_FMT_SECONDARY_INTERVIEW"}"
HEADER_RG_FMT_SECONDARY_AUDIOBOOK="${HEADER_RG_FMT_SECONDARY_AUDIOBOOK:-"$RGV_FMT_SECONDARY_AUDIOBOOK"}"
HEADER_RG_FMT_SECONDARY_AUDIODRAMA="${HEADER_RG_FMT_SECONDARY_AUDIODRAMA:-"$RGV_FMT_SECONDARY_AUDIODRAMA"}"
HEADER_RG_FMT_SECONDARY_LIVE="${HEADER_RG_FMT_SECONDARY_LIVE:-"$RGV_FMT_SECONDARY_LIVE"}"
HEADER_RG_FMT_SECONDARY_REMIX="${HEADER_RG_FMT_SECONDARY_REMIX:-"$RGV_FMT_SECONDARY_REMIX"}"
HEADER_RG_FMT_SECONDARY_DJMIX="${HEADER_RG_FMT_SECONDARY_DJMIX:-"$RGV_FMT_SECONDARY_DJMIX"}"
HEADER_RG_FMT_SECONDARY_MIXTAPE="${HEADER_RG_FMT_SECONDARY_MIXTAPE:-"$RGV_FMT_SECONDARY_MIXTAPE"}"
HEADER_RG_FMT_SECONDARY_DEMO="${HEADER_RG_FMT_SECONDARY_DEMO:-"$RGV_FMT_SECONDARY_DEMO"}"
HEADER_RG_FMT_SECONDARY_FIELDREC="${HEADER_RG_FMT_SECONDARY_FIELDREC:-"$RGV_FMT_SECONDARY_FIELDREC"}"
HEADER_RG_FMT_TITLE="${HEADER_RG_FMT_TITLE:-"$RGV_FMT_TITLE"}"
HEADER_RG_FMT_ARTIST="${HEADER_RG_FMT_ARTIST:-"${CARTIST}%s$OFF"}"
HEADER_RG_FMT_YEAR="${HEADER_RG_FMT_YEAR:-"$RGV_FMT_YEAR"}"
export HEADER_RG_FMT HEADER_RG_FMT_CNT HEADER_RG_FMT_RIGHTALIGN \
HEADER_RG_FMT_FLAG_LOCAL HEADER_RG_FMT_FLAG_NO_LOCAL \
HEADER_RG_FMT_TYPE_SINGLE HEADER_RG_FMT_TYPE_ALBUM HEADER_RG_FMT_TYPE_EP \
HEADER_RG_FMT_TYPE_BROADCAST HEADER_RG_FMT_TYPE_OTHER \
HEADER_RG_FMT_TYPE_UNKNOWN HEADER_RG_FMT_HASSECONDARY_YES \
HEADER_RG_FMT_HASSECONDARY_NO HEADER_RG_FMT_SECONDARY \
HEADER_RG_FMT_SECONDARY_SOUNDTRACK HEADER_RG_FMT_SECONDARY_SPOKENWORD \
HEADER_RG_FMT_SECONDARY_INTERVIEW HEADER_RG_FMT_SECONDARY_AUDIOBOOK \
HEADER_RG_FMT_SECONDARY_AUDIODRAMA HEADER_RG_FMT_SECONDARY_LIVE \
HEADER_RG_FMT_SECONDARY_REMIX HEADER_RG_FMT_SECONDARY_DJMIX \
HEADER_RG_FMT_SECONDARY_MIXTAPE HEADER_RG_FMT_SECONDARY_DEMO \
HEADER_RG_FMT_SECONDARY_FIELDREC HEADER_RG_FMT_TITLE HEADER_RG_FMT_ARTIST \
HEADER_RG_FMT_YEAR
# Recording view # Header that displays the release (based on release view)
# ============== #HEADER_RELEASE="${HEADER_RELEASE:-" ${CARTIST}%s$OFF 》${CTITLE}%s$OFF 〉%s"}"
# Format of a track in a release #HEADER_RELEASE_FORMAT="${HEADER_RELEASE_FORMAT:-"${CRELINFO}<<tracks>> tx <<media>> $OFF|$CRELINFO <<label>> <<country>> <<year>>$OFF"}"
REC_FORMAT="${REC_FORMAT:-"${CNOTE}${FAINT}<<med>>\t${CNOTE}<<nr>>$OFF\t${CTITLE}<<title>>\t${CARTIST}<<artist>>\t${CXXX}<<duration>>$OFF"}" HEADER_R_FMT="${HEADER_R_FMT:-"🎤\t<<artist>> 》<<title>> 〉<<tracks>> ${CRELINFO}tx${OFF} <<media>> | <<label>> <<country>> <<year>>"}"
# Format of a track in the playlist HEADER_R_FMT_CNT=$(($(printf "$HEADER_R_FMT" | tr -cd '\t' | wc -c) + 1))
REC_FORMAT_NO_NUMBER="${REC_FORMAT_NO_NUMBER:-"${CTITLE}<<title>>\t${CARTIST}<<artist>>\t${CXXX}<<duration>>$OFF"}" HEADER_R_FMT_RIGHTALIGN="${HEADER_R_FMT_RIGHTALIGN:-"1"}"
export REC_FORMAT REC_FORMAT_NO_NUMBER HEADER_R_FMT_FLAG_LOCAL="${HEADER_R_FMT_FLAG_LOCAL:-"$RV_FMT_FLAG_LOCAL"}"
HEADER_R_FMT_FLAG_NO_LOCAL="${HEADER_R_FMT_FLAG_NO_LOCAL:-"$RV_FMT_FLAG_NO_LOCAL"}"
HEADER_R_FMT_STATUS_OFFICIAL="${HEADER_R_FMT_STATUS_OFFICIAL:-"$RV_FMT_STATUS_OFFICIAL"}"
HEADER_R_FMT_STATUS_PROMO="${HEADER_R_FMT_STATUS_PROMO:-"$RV_FMT_STATUS_PROMO"}"
HEADER_R_FMT_STATUS_BOOTLEG="${HEADER_R_FMT_STATUS_BOOTLEG:-"$RV_FMT_STATUS_BOOTLEG"}"
HEADER_R_FMT_STATUS_PSEUDO="${HEADER_R_FMT_STATUS_PSEUDO:-"$RV_FMT_STATUS_PSEUDO"}"
HEADER_R_FMT_STATUS_WITHDRAWN="${HEADER_R_FMT_STATUS_WITHDRAWN:-"$RV_FMT_STATUS_WITHDRAWN"}"
HEADER_R_FMT_STATUS_EXPUNGED="${HEADER_R_FMT_STATUS_EXPUNGED:-"$RV_FMT_STATUS_EXPUNGED"}"
HEADER_R_FMT_STATUS_CANCELLED="${HEADER_R_FMT_STATUS_CANCELLED:-"$RV_FMT_STATUS_CANCELLED"}"
HEADER_R_FMT_STATUS_UNKNOWN="${HEADER_R_FMT_STATUS_UNKNOWN:-"$RV_FMT_STATUS_UNKNOWN"}"
HEADER_R_FMT_TRACKS="${HEADER_R_FMT_TRACKS:-"${CRELINFO}%s$OFF"}"
HEADER_R_FMT_MEDIA="${HEADER_R_FMT_MEDIA:-"${CRELINFO}%s$OFF"}"
HEADER_R_FMT_YEAR="${HEADER_R_FMT_YEAR:-"${CRELINFO}%s$OFF"}"
HEADER_R_FMT_COUNTRY="${HEADER_R_FMT_COUNTRY:-"${CRELINFO}%s$OFF"}"
HEADER_R_FMT_LABEL="${HEADER_R_FMT_LABEL:-"${CRELINFO}%s$OFF"}"
HEADER_R_FMT_TITLE="${HEADER_R_FMT_TITLE:-"${CTITLE}%s$OFF"}"
HEADER_R_FMT_ARTIST="${HEADER_R_FMT_ARTIST:-"${CARTIST}%s$OFF"}"
export HEADER_R_FMT HEADER_R_FMT_CNT HEADER_R_FMT_RIGHTALIGN \
HEADER_R_FMT_FLAG_LOCAL HEADER_R_FMT_FLAG_NO_LOCAL \
HEADER_R_FMT_STATUS_OFFICIAL HEADER_R_FMT_STATUS_PROMO \
HEADER_R_FMT_STATUS_BOOTLEG HEADER_R_FMT_STATUS_PSEUDO \
HEADER_R_FMT_STATUS_WITHDRAWN HEADER_R_FMT_STATUS_EXPUNGED \
HEADER_R_FMT_STATUS_CANCELLED HEADER_R_FMT_STATUS_UNKNOWN \
HEADER_R_FMT_TRACKS HEADER_R_FMT_MEDIA HEADER_R_FMT_YEAR \
HEADER_R_FMT_COUNTRY HEADER_R_FMT_LABEL HEADER_R_FMT_TITLE \
HEADER_R_FMT_ARTIST
# Keybinding themes # Artist Preview
# ================= # ==============
# Format keybinding group # Main preview format. Takes two %s placeholder. The first is for the artist
KBF_GROUP="${KBF_GROUP:-"${UNDERLINE}${CKB}%s$OFF"}" # biography. The second for the life span.
# Format key APV_FORMAT="${APV_FORMAT:-"\n\n${CDESC}%s${OFF}\n\n${CLIFE}%s${OFF}"}"
KBF_KEY="${KBF_KEY:-"${BOLD}${CKB}%s$OFF"}" # Specification of a date
# Format description APV_DATE="${APV_DATE:-"%s"}"
KBF_DESC="${KBF_DESC:-"${CKB}%s$OFF"}" # Specification of a place
export KBF_GROUP KBF_KEY KBF_DESC APV_PLACE="${APV_PLACE:-"%s"}"
# Specification of a date and a place (in that order)
APV_DATEPLACE="${APV_DATEPLACE:-"$APV_DATE, $APV_PLACE"}"
# String to represent when/where a person is born
APV_BORN="${APV_BORN:-"🍼 Born: %s"}"
# String to represent when/where a person died
APV_DIED="${APV_DIED:-"🕯️ Died: %s"}"
export APV_FORMAT APV_DATE APV_PLACE APV_DATEPLACE APV_BORN APV_DIED
# Keybinding themes
# =================
# Format keybinding group
KBF_GROUP="${KBF_GROUP:-"${UNDERLINE}${CKB}%s$OFF"}"
# Format key
KBF_KEY="${KBF_KEY:-"${BOLD}${CKB}%s$OFF"}"
# Format description
KBF_DESC="${KBF_DESC:-"${CKB}%s$OFF"}"
export KBF_GROUP KBF_KEY KBF_DESC
export THEME_LOADED=1
fi