Track local files
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
content
|
||||||
|
public
|
||||||
58
chordpro.json
Normal file
58
chordpro.json
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
pdf {
|
||||||
|
papersize : a4
|
||||||
|
columnspace : 20
|
||||||
|
margintop : 60
|
||||||
|
marginbottom : 40
|
||||||
|
marginleft : 40
|
||||||
|
marginright : 40
|
||||||
|
headspace : 40
|
||||||
|
footspace : 20
|
||||||
|
|
||||||
|
formats.title {
|
||||||
|
title : [ "" "%{title}" "%{artist}" ]
|
||||||
|
subtitle : [ "" "" "" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
fontdir : [ static/fonts/liberation-fonts-ttf-2.1.5/ ]
|
||||||
|
fontconfig {
|
||||||
|
serif {
|
||||||
|
"" : LiberationSerif-Regular.ttf
|
||||||
|
bold : LiberationSerif-Bold.ttf
|
||||||
|
italic : LiberationSerif-Italic.ttf
|
||||||
|
bolditalic : LiberationSerif-BoldItalic.ttf
|
||||||
|
}
|
||||||
|
sans {
|
||||||
|
"" : LiberationSans-Regular.ttf
|
||||||
|
bold : LiberationSans-Bold.ttf
|
||||||
|
italic : LiberationSans-Italic.ttf
|
||||||
|
bolditalic : LiberationSans-BoldItalic.ttf
|
||||||
|
}
|
||||||
|
monospace {
|
||||||
|
"" : LiberationMono-Regular.ttf
|
||||||
|
bold : LiberationMono-Bold.ttf
|
||||||
|
italic : LiberationMono-Italic.ttf
|
||||||
|
bolditalic : LiberationMono-BoldItalic.ttf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fonts {
|
||||||
|
title.description : "serif bold 14"
|
||||||
|
subtitle.description : "serif 11"
|
||||||
|
text.description : "serif 12"
|
||||||
|
chord.description : "sans italic 10"
|
||||||
|
comment {
|
||||||
|
description : "sans 12"
|
||||||
|
background : #E5E5E5
|
||||||
|
}
|
||||||
|
comment_italic.description : "sans italic 12"
|
||||||
|
comment_box {
|
||||||
|
description : "sans 12"
|
||||||
|
frame : 1
|
||||||
|
}
|
||||||
|
tab.description : "monospace 10"
|
||||||
|
toc.description : "serif 11"
|
||||||
|
grid.description : "sans 10"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html.styles.display : /chordpro.css
|
||||||
20
config.toml
Normal file
20
config.toml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
base_url = "https://mixtape.0x45.cz"
|
||||||
|
title = "mixtape"
|
||||||
|
compile_sass = true
|
||||||
|
build_search_index = false
|
||||||
|
generate_feeds = false
|
||||||
|
|
||||||
|
taxonomies = [
|
||||||
|
{ name = "category" },
|
||||||
|
{ name = "artist" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[markdown]
|
||||||
|
highlight_code = false
|
||||||
|
smart_punctuation = true
|
||||||
|
external_links_target_blank = true
|
||||||
|
external_links_no_follow = true
|
||||||
|
external_links_no_referrer = true
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
git_repository = "https://git.0x45.cz/em/mixtape"
|
||||||
52
makefile
Normal file
52
makefile
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
ifdef CHORDPRO_PIPELINE
|
||||||
|
CHORDPRO_CMD = chordpro
|
||||||
|
else
|
||||||
|
CHORDPRO_CMD = docker run --rm \
|
||||||
|
--env HOME=$(HOME) --env USER=$(USER) \
|
||||||
|
--workdir $(shell pwd) \
|
||||||
|
--volume $(HOME):$(HOME) \
|
||||||
|
chordpro/chordpro:latest chordpro --config=chordpro.json
|
||||||
|
endif
|
||||||
|
|
||||||
|
SRC_EXTENSION := .cho
|
||||||
|
CURRENT_DIR := content/current
|
||||||
|
ARCHIVE_DIR := content/archive
|
||||||
|
|
||||||
|
# Find all .cho files in both current and archive
|
||||||
|
SONG_CHO := $(shell find $(CURRENT_DIR) $(ARCHIVE_DIR) -type f -name "*$(SRC_EXTENSION)")
|
||||||
|
SONG_PDF := $(SONG_CHO:$(SRC_EXTENSION)=.pdf)
|
||||||
|
SONG_HTML := $(SONG_CHO:$(SRC_EXTENSION)=.html)
|
||||||
|
|
||||||
|
# Songbook only includes current songs (sorted alphabetically)
|
||||||
|
CURRENT_CHO := $(shell find $(CURRENT_DIR) -type f -name "*$(SRC_EXTENSION)" | sort)
|
||||||
|
CURRENT_PDF := $(CURRENT_CHO:$(SRC_EXTENSION)=.pdf)
|
||||||
|
SONGBOOK := content/songbook.pdf
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := pdf
|
||||||
|
|
||||||
|
# Pattern rules that work for nested directories
|
||||||
|
content/%.pdf: content/%$(SRC_EXTENSION)
|
||||||
|
@echo "Building PDF: $@"
|
||||||
|
$(CHORDPRO_CMD) -o $@ $<
|
||||||
|
|
||||||
|
content/%.html: content/%$(SRC_EXTENSION)
|
||||||
|
@echo "Building HTML: $@"
|
||||||
|
$(CHORDPRO_CMD) -o $@ $<
|
||||||
|
|
||||||
|
# Aggregate targets
|
||||||
|
all: pdf html songbook
|
||||||
|
|
||||||
|
pdf: $(SONG_PDF)
|
||||||
|
|
||||||
|
html: $(SONG_HTML)
|
||||||
|
|
||||||
|
songbook: $(SONGBOOK)
|
||||||
|
|
||||||
|
# Songbook combines alphabetically sorted PDFs
|
||||||
|
$(SONGBOOK): $(CURRENT_PDF)
|
||||||
|
@echo "Creating songbook (alphabetically sorted)..."
|
||||||
|
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=$@ $(CURRENT_PDF)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(SONG_PDF) $(SONG_HTML) $(SONGBOOK)
|
||||||
|
|
||||||
76
manage
Executable file
76
manage
Executable file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
SONGS_PATH="content/current/"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 <command> [options]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
help Show this help message and exit
|
||||||
|
new [name] Create a new song [with the specified name]
|
||||||
|
edit <name> Edit song with a text editor
|
||||||
|
iedit <name> Interactive edit with PDF preview
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
$0 help
|
||||||
|
$0 new [song-name]
|
||||||
|
$0 edit <song-name>
|
||||||
|
$0 iedit <song-name>
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
create_new_song() {
|
||||||
|
if [ -z "$name" ]; then
|
||||||
|
read -p "Song name (file-name-in-path): " name
|
||||||
|
fi
|
||||||
|
read -p "Song title: " title
|
||||||
|
read -p "Artist: " artist
|
||||||
|
read -p "Category: " category
|
||||||
|
|
||||||
|
mkdir -p "$SONGS_PATH/$name"
|
||||||
|
echo -e "{title: $title}\n{artist: $artist}" > "$SONGS_PATH/$name/$name.cho"
|
||||||
|
echo -e "+++\ntitle = \"$title\"\n[taxonomies]\ncategory = [\"$category\"]\nartist = [\"$artist\"]\n+++" > "$SONGS_PATH/$name/index.md"
|
||||||
|
echo "Song $name created."
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$#" -lt 1 ]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
new)
|
||||||
|
if [ "$#" -eq 2 ]; then
|
||||||
|
name="$2"
|
||||||
|
fi
|
||||||
|
create_new_song
|
||||||
|
;;
|
||||||
|
edit)
|
||||||
|
if [ "$#" -eq 2 ]; then
|
||||||
|
xdg-open "$SONGS_PATH/$2/$2.cho"
|
||||||
|
else
|
||||||
|
echo -e "Missing song name\n"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
iedit)
|
||||||
|
if [ "$#" -eq 2 ]; then
|
||||||
|
touch "$SONGS_PATH/$2/$2.pdf"
|
||||||
|
xdg-open "$SONGS_PATH/$2/$2.pdf" &
|
||||||
|
xdg-open "$SONGS_PATH/$2/$2.cho"
|
||||||
|
else
|
||||||
|
echo -e "Missing song name\n"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "Invalid argument: $1\n"
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
62
readme.md
Normal file
62
readme.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
My personal guitar chord-book written in [ChordPro](https://www.chordpro.org/).
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- `docker`
|
||||||
|
- `ghostscript` (optional for `songbook` make target)
|
||||||
|
- `zola` (optional for web deployment)
|
||||||
|
|
||||||
|
The makefile uses Docker with the official iamge `chordpro/chordpro:latest`.
|
||||||
|
It can be seamlesly integrated with a shell alias in case you want to use
|
||||||
|
ChordPro directly in your shell outside of make:
|
||||||
|
|
||||||
|
```
|
||||||
|
alias chordpro="docker run -ti --rm --env HOME=\$HOME --env USER=\$USER --workdir \$(pwd) --volume \$HOME:\$HOME chordpro/chordpro:latest chordpro"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
`make` defaults to `pdf` which builds individual PDF files for all songs.
|
||||||
|
|
||||||
|
Target | Description
|
||||||
|
-|-
|
||||||
|
`all` | `pdf`, `html`, `songbook`
|
||||||
|
`pdf` | Build individual PDF files
|
||||||
|
`html` | Build individual HTML files
|
||||||
|
`songbook` | Build one complete PDF songbook with all songs
|
||||||
|
`clean` | Remove all generated files
|
||||||
|
|
||||||
|
The makefile is ready for parallel building:
|
||||||
|
|
||||||
|
```
|
||||||
|
make -j$(nproc)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also build PDF for a specific page with:
|
||||||
|
|
||||||
|
```
|
||||||
|
chordpro --config=chordpro.json path/to/song.cho
|
||||||
|
```
|
||||||
|
|
||||||
|
or build HTML output with:
|
||||||
|
|
||||||
|
```
|
||||||
|
chordpro --config=chordpro.json -o path/to/song.html path/to/song.cho
|
||||||
|
```
|
||||||
|
|
||||||
|
### Static website output
|
||||||
|
|
||||||
|
Futhermore, the project is ready to be compiled into a static webpage using
|
||||||
|
[Zola](https://www.getzola.org/).
|
||||||
|
|
||||||
|
```
|
||||||
|
zola build
|
||||||
|
```
|
||||||
|
|
||||||
|
This is done by default during the deploy pipeline.
|
||||||
|
|
||||||
|
## Song management
|
||||||
|
|
||||||
|
The `manage` shell script lets you do basic song management and saves you some
|
||||||
|
manual labour. Simply run the script itself or invoke `help` to get a list of
|
||||||
|
all available commands.
|
||||||
1
sass/_fonts.scss
Normal file
1
sass/_fonts.scss
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,600;1,400;1,600&display=swap');
|
||||||
80
sass/chordpro.scss
Normal file
80
sass/chordpro.scss
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
@import "fonts";
|
||||||
|
|
||||||
|
$col-white: #fff;
|
||||||
|
$col-black: #2e3440;
|
||||||
|
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background-color: $col-black;
|
||||||
|
color: $col-white;
|
||||||
|
font-family: "Noto Sans", Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
text-rendering: geometricPrecision;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
transition: transform ease-out .25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.song {
|
||||||
|
padding: 3em 0 1em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chords {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chorus, .verse, .tab {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chorus {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: -1em;
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 2px;
|
||||||
|
background-color: $col-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
white-space: pre;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
display: inline-block;
|
||||||
|
padding: .25em .5em;
|
||||||
|
background-color: #4c566a;
|
||||||
|
color: $col-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
body {
|
||||||
|
background-color: $col-white;
|
||||||
|
color: $col-black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chorus:before {
|
||||||
|
background-color: $col-black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
background-color: #d8dee9;
|
||||||
|
color: $col-black;
|
||||||
|
}
|
||||||
|
}
|
||||||
247
sass/style.scss
Normal file
247
sass/style.scss
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
@import "fonts";
|
||||||
|
|
||||||
|
$width-mobile: 900px;
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #2e3440;
|
||||||
|
color: #fff;
|
||||||
|
font-family: "Noto Sans", Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
text-rendering: geometricPrecision;
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #2e3440;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main.songs {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1em;
|
||||||
|
max-width: 50em;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
@media only screen and (max-width: $width-mobile) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters, .nav {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||||
|
gap: 1em;
|
||||||
|
margin: 1em 0;
|
||||||
|
|
||||||
|
// This is removed via JS to prevent displaying the inputs
|
||||||
|
// on browsers wih JavaScript disabled.
|
||||||
|
&.hidden { display: none }
|
||||||
|
|
||||||
|
&>* {
|
||||||
|
border-radius: .5em;
|
||||||
|
box-shadow: rgba(15, 17, 21, 0.5) 0px 3px 6px 0px;
|
||||||
|
background-color: #3b4252;
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #2e3440;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
grid-column: 1 / 3;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-size: inherit;
|
||||||
|
border: 0;
|
||||||
|
background-color: inherit;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="search"] {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: .75em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="reset"] {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 3em;
|
||||||
|
padding: 0;
|
||||||
|
background-size: auto 1.5em;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(160,163,170,1)'%3E%3Cpath d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 10.5858L14.8284 7.75736L16.2426 9.17157L13.4142 12L16.2426 14.8284L14.8284 16.2426L12 13.4142L9.17157 16.2426L7.75736 14.8284L10.5858 12L7.75736 9.17157L9.17157 7.75736L12 10.5858Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&>.button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: .5em;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
padding: .75em 1em;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
color: #fff;
|
||||||
|
&[data-category="mixtape"] { background-color: #bf616a }
|
||||||
|
&[data-category="classic"] { background-color: #5e81ac }
|
||||||
|
}
|
||||||
|
|
||||||
|
&.wide { grid-column: 1 / 3 }
|
||||||
|
|
||||||
|
& svg {
|
||||||
|
height: 1.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: $width-mobile) {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.nav { margin-bottom: 0 }
|
||||||
|
|
||||||
|
.song-list {
|
||||||
|
display: grid;
|
||||||
|
gap: 1em;
|
||||||
|
|
||||||
|
&>div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1em;
|
||||||
|
padding: .5em;
|
||||||
|
padding-left: 1em;
|
||||||
|
border-radius: .5em;
|
||||||
|
box-shadow: rgba(15, 17, 21, 0.5) 0px 3px 6px 0px;
|
||||||
|
border-left: .7em solid #000;
|
||||||
|
background-color: #3b4252;
|
||||||
|
|
||||||
|
&.hidden { display: none }
|
||||||
|
|
||||||
|
&.mixtape { border-color: #bf616a }
|
||||||
|
&.classic { border-color: #5e81ac }
|
||||||
|
|
||||||
|
.meta {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.title { font-weight: bold }
|
||||||
|
.artist { font-size: .8em }
|
||||||
|
}
|
||||||
|
|
||||||
|
.links {
|
||||||
|
display: flex;
|
||||||
|
gap: .5em;
|
||||||
|
|
||||||
|
&>* {
|
||||||
|
height: 2.75em;
|
||||||
|
width: 2.75em;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: auto 1.5em;
|
||||||
|
border-radius: .25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.html {
|
||||||
|
background-color: #5e81ac;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,1)'%3E%3Cpath d='M16 2L21 7V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5447 3 21.0082V2.9918C3 2.44405 3.44495 2 3.9934 2H16ZM17.6569 12L14.1213 8.46447L12.7071 9.87868L14.8284 12L12.7071 14.1213L14.1213 15.5355L17.6569 12ZM6.34315 12L9.87868 15.5355L11.2929 14.1213L9.17157 12L11.2929 9.87868L9.87868 8.46447L6.34315 12Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdf {
|
||||||
|
background-color: #bf616a;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,1)'%3E%3Cpath d='M3.9985 2C3.44749 2 3 2.44405 3 2.9918V21.0082C3 21.5447 3.44476 22 3.9934 22H20.0066C20.5551 22 21 21.5489 21 20.9925L20.9997 7L16 2H3.9985ZM10.5 7.5H12.5C12.5 9.98994 14.6436 12.6604 17.3162 13.5513L16.8586 15.49C13.7234 15.0421 10.4821 16.3804 7.5547 18.3321L6.3753 16.7191C7.46149 15.8502 8.50293 14.3757 9.27499 12.6534C10.0443 10.9373 10.5 9.07749 10.5 7.5ZM11.1 13.4716C11.3673 12.8752 11.6043 12.2563 11.8037 11.6285C12.2754 12.3531 12.8553 13.0182 13.5102 13.5953C12.5284 13.7711 11.5666 14.0596 10.6353 14.4276C10.8 14.1143 10.9551 13.7948 11.1 13.4716Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #2e3440;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main.song {
|
||||||
|
height: 100dvh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: 50em;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding-left: .5em;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 2em;
|
||||||
|
background-color: #3b4252;
|
||||||
|
|
||||||
|
section {
|
||||||
|
display:flex;
|
||||||
|
|
||||||
|
&.font-size>.button:hover, &.font-size>.button.active { background-color: #bf616a }
|
||||||
|
&.transpose>.button:hover, &.transpose>.button.active { background-color: #5e81ac }
|
||||||
|
&.autoscroll>.button:hover, &.autoscroll>.button.active { background-color: #d08770 }
|
||||||
|
&.autoscroll>#autoscroll.active { background-color: #bf616a }
|
||||||
|
|
||||||
|
.button{
|
||||||
|
display: grid;
|
||||||
|
align-items: center;
|
||||||
|
justify-items: center;
|
||||||
|
height: 2.5em;
|
||||||
|
width: 2.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
background-position: center;
|
||||||
|
background-size: 1.5em;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
|
||||||
|
|
||||||
|
&.icon-add {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,1)'%3E%3Cpath d='M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
&.icon-subtract {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,1)'%3E%3Cpath d='M5 11V13H19V11H5Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
&.icon-font-size {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,1)'%3E%3Cpath d='M11.246 15H4.75416L2.75416 20H0.600098L7.0001 4H9.0001L15.4001 20H13.246L11.246 15ZM10.446 13L8.0001 6.88516L5.55416 13H10.446ZM21.0001 12.5351V12H23.0001V20H21.0001V19.4649C20.4118 19.8052 19.7287 20 19.0001 20C16.791 20 15.0001 18.2091 15.0001 16C15.0001 13.7909 16.791 12 19.0001 12C19.7287 12 20.4118 12.1948 21.0001 12.5351ZM19.0001 18C20.1047 18 21.0001 17.1046 21.0001 16C21.0001 14.8954 20.1047 14 19.0001 14C17.8955 14 17.0001 14.8954 17.0001 16C17.0001 17.1046 17.8955 18 19.0001 18Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
&.icon-transpose {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,1)'%3E%3Cpath d='M12 13.5351V3H20V5H14V17C14 19.2091 12.2091 21 10 21C7.79086 21 6 19.2091 6 17C6 14.7909 7.79086 13 10 13C10.7286 13 11.4117 13.1948 12 13.5351ZM10 19C11.1046 19 12 18.1046 12 17C12 15.8954 11.1046 15 10 15C8.89543 15 8 15.8954 8 17C8 18.1046 8.89543 19 10 19Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
&.icon-scroll {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='rgba(255,255,255,1)'%3E%3Cpath d='M12 10.0858L7.20712 5.29291L5.79291 6.70712L12 12.9142L18.2071 6.70712L16.7929 5.29291L12 10.0858ZM18 17L6.00001 17L6.00001 15L18 15V17Z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: $width-mobile) {
|
||||||
|
gap: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is removed via JS to prevent displaying the controls
|
||||||
|
// on browsers wih JavaScript disabled.
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
static/favicon.png
Normal file
BIN
static/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
16
static/fonts/liberation-fonts-ttf-2.1.5/AUTHORS
Normal file
16
static/fonts/liberation-fonts-ttf-2.1.5/AUTHORS
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
AUTHORS
|
||||||
|
|
||||||
|
Current Contributors (sorted alphabetically):
|
||||||
|
|
||||||
|
- Vishal Vijayraghavan <vishalvvr at fedoraproject dot org>
|
||||||
|
Project Owner/ Maintainer (Current)
|
||||||
|
Red Hat, Inc.
|
||||||
|
|
||||||
|
Previous Contributors
|
||||||
|
- Pravin Satpute <psatpute at redhat dot com>
|
||||||
|
Project Owner/ Maintainer
|
||||||
|
Red Hat, Inc.
|
||||||
|
|
||||||
|
- Steve Matteson
|
||||||
|
Original Designer
|
||||||
|
Ascender, Inc.
|
||||||
102
static/fonts/liberation-fonts-ttf-2.1.5/LICENSE
Normal file
102
static/fonts/liberation-fonts-ttf-2.1.5/LICENSE
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
Digitized data copyright (c) 2010 Google Corporation
|
||||||
|
with Reserved Font Arimo, Tinos and Cousine.
|
||||||
|
Copyright (c) 2012 Red Hat, Inc.
|
||||||
|
with Reserved Font Name Liberation.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License,
|
||||||
|
Version 1.1.
|
||||||
|
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
|
||||||
|
PREAMBLE The goals of the Open Font License (OFL) are to stimulate
|
||||||
|
worldwide development of collaborative font projects, to support the font
|
||||||
|
creation efforts of academic and linguistic communities, and to provide
|
||||||
|
a free and open framework in which fonts may be shared and improved in
|
||||||
|
partnership with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves.
|
||||||
|
The fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply to
|
||||||
|
any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such.
|
||||||
|
This may include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components
|
||||||
|
as distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting ? in part or in whole ?
|
||||||
|
any of the components of the Original Version, by changing formats or
|
||||||
|
by porting the Font Software to a new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical writer
|
||||||
|
or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,in
|
||||||
|
Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the
|
||||||
|
corresponding Copyright Holder. This restriction only applies to the
|
||||||
|
primary font name as presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole, must
|
||||||
|
be distributed entirely under this license, and must not be distributed
|
||||||
|
under any other license. The requirement for fonts to remain under
|
||||||
|
this license does not apply to any document created using the Font
|
||||||
|
Software.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are not met.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
|
||||||
|
DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|
||||||
BIN
static/fonts/liberation-fonts-ttf-2.1.5/LiberationMono-Bold.ttf
Normal file
BIN
static/fonts/liberation-fonts-ttf-2.1.5/LiberationMono-Bold.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
static/fonts/liberation-fonts-ttf-2.1.5/LiberationSans-Bold.ttf
Normal file
BIN
static/fonts/liberation-fonts-ttf-2.1.5/LiberationSans-Bold.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
static/fonts/liberation-fonts-ttf-2.1.5/LiberationSerif-Bold.ttf
Normal file
BIN
static/fonts/liberation-fonts-ttf-2.1.5/LiberationSerif-Bold.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
53
static/js/filter.js
Normal file
53
static/js/filter.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
const filters = document.querySelector(".filters");
|
||||||
|
const buttons = Array.from(filters.querySelectorAll(".button"));
|
||||||
|
const search = document.querySelector("input[type='search']");
|
||||||
|
const form = document.querySelector("form");
|
||||||
|
const songList = document.querySelector(".song-list");
|
||||||
|
|
||||||
|
let selectedCategory = null;
|
||||||
|
|
||||||
|
function buttonToggle(clickedButton) {
|
||||||
|
buttons.forEach(button => {
|
||||||
|
if (button === clickedButton && !button.classList.contains("selected")) {
|
||||||
|
button.classList.add("selected");
|
||||||
|
selectedCategory = button.dataset.category;
|
||||||
|
} else {
|
||||||
|
button.classList.remove("selected");
|
||||||
|
if (button.dataset.category == selectedCategory) selectedCategory = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
filterSongs();
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterSongs() {
|
||||||
|
const searchTerm = sanitizeString(search.value);
|
||||||
|
const songs = Array.from(songList.children);
|
||||||
|
songs.forEach(song => {
|
||||||
|
const matching = (
|
||||||
|
(song.dataset.title.includes(searchTerm) || (song.dataset.artist && song.dataset.artist.includes(searchTerm))) &&
|
||||||
|
(!selectedCategory || song.dataset.category === selectedCategory)
|
||||||
|
);
|
||||||
|
song.classList.toggle("hidden", !matching);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizeString(string) {
|
||||||
|
return string.trim().toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listeners
|
||||||
|
search.addEventListener("input", filterSongs);
|
||||||
|
// Filtering happens before the reset itself without this timeout
|
||||||
|
form.addEventListener("reset", () => setTimeout(filterSongs, 0));
|
||||||
|
buttons.forEach(button => button.addEventListener("click", () => buttonToggle(button)));
|
||||||
|
|
||||||
|
// Normalize song titles
|
||||||
|
Array.from(songList.children).forEach(song => {
|
||||||
|
song.dataset.title = sanitizeString(song.dataset.title);
|
||||||
|
if (song.dataset.artist) {
|
||||||
|
song.dataset.artist = sanitizeString(song.dataset.artist);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Display the filter section on JS-enabled browsers
|
||||||
|
window.addEventListener("load", () => filters.classList.remove = "hidden");
|
||||||
58
static/js/song-controls.js
Normal file
58
static/js/song-controls.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
const controls = document.querySelector(".controls");
|
||||||
|
const song = document.querySelector("iframe.song").contentWindow;
|
||||||
|
|
||||||
|
// Autoscroll
|
||||||
|
var scroll;
|
||||||
|
var scrollTimeout = 60;
|
||||||
|
const minTimeout = 10;
|
||||||
|
const maxTimeout = 120;
|
||||||
|
const scrollIncrement = 20;
|
||||||
|
|
||||||
|
function pageScroll() {
|
||||||
|
song.scrollBy(0, 1);
|
||||||
|
scroll = setTimeout(pageScroll, scrollTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateScrollSpeed() {
|
||||||
|
if (controls.querySelector("#autoscroll").classList.contains("active")) {
|
||||||
|
clearTimeout(scroll);
|
||||||
|
scroll = setTimeout(pageScroll, scrollTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.querySelector("#autoscroll-increase").addEventListener("click", () => {
|
||||||
|
scrollTimeout = Math.max(minTimeout, scrollTimeout - scrollIncrement);
|
||||||
|
updateScrollSpeed();
|
||||||
|
});
|
||||||
|
|
||||||
|
controls.querySelector("#autoscroll-decrease").addEventListener("click", () => {
|
||||||
|
scrollTimeout = Math.min(maxTimeout, scrollTimeout + scrollIncrement);
|
||||||
|
updateScrollSpeed();
|
||||||
|
});
|
||||||
|
|
||||||
|
controls.querySelector("#autoscroll").addEventListener("click", function() {
|
||||||
|
this.classList.toggle("active");
|
||||||
|
if (this.classList.contains("active")) {
|
||||||
|
pageScroll();
|
||||||
|
} else {
|
||||||
|
clearTimeout(scroll);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scaling
|
||||||
|
function pageScale(value) {
|
||||||
|
if (value === 0) {
|
||||||
|
song.document.body.style.transform = "scale(1)";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const currentScale = parseFloat(song.document.body.style.transform.split("scale(")[1]) || 1;
|
||||||
|
song.document.body.style.transform = "scale(" + (currentScale + value) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.querySelector("#font-size-increase").addEventListener("click", () => pageScale(0.1));
|
||||||
|
controls.querySelector("#font-size-decrease").addEventListener("click", () => pageScale(-0.1));
|
||||||
|
controls.querySelector("#font-size-reset").addEventListener("click", () => pageScale(0));
|
||||||
|
|
||||||
|
|
||||||
|
// Display the controls on JS-enabled browsers
|
||||||
|
window.addEventListener("load", () => controls.classList.remove = "hidden");
|
||||||
6
templates/files.html
Normal file
6
templates/files.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{% extends "index.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<main>
|
||||||
|
files here
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
||||||
81
templates/index.html
Normal file
81
templates/index.html
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
{% import "macros.html" as macros %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}{{ config.title }}{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" href="{{ get_url(path="/style.css") }}">
|
||||||
|
<link rel="icon" type="image/png" href="{{ get_url(path="/favicon.png") }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% block content %}
|
||||||
|
<main class="songs">
|
||||||
|
{% if section.extra.archive %}
|
||||||
|
<section class="nav">
|
||||||
|
<a href="{{ get_url(path="@/_index.md") }}" class="button wide">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22.0003 12.9999L22.0004 11L8.41421 11V5.58582L2 12L8.41421 18.4142L8.41421 13L22.0003 12.9999Z"></path></svg>
|
||||||
|
Back From Archive
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
{% else %}
|
||||||
|
<section class="nav">
|
||||||
|
<a href="{{ get_url(path="@/archive/_index.md") }}" class="button">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 10H2V4.00293C2 3.44903 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.43788 22 4.00293V10H21V20.0015C21 20.553 20.5551 21 20.0066 21H3.9934C3.44476 21 3 20.5525 3 20.0015V10ZM19 10H5V19H19V10ZM4 5V8H20V5H4ZM9 12H15V14H9V12Z"></path></svg>
|
||||||
|
Archive
|
||||||
|
</a>
|
||||||
|
<a href="{{ get_url(path="/songbook.pdf") }}" target="_blank" class="button">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 18.5V5C3 3.34315 4.34315 2 6 2H20C20.5523 2 21 2.44772 21 3V21C21 21.5523 20.5523 22 20 22H6.5C4.567 22 3 20.433 3 18.5ZM19 20V17H6.5C5.67157 17 5 17.6716 5 18.5C5 19.3284 5.67157 20 6.5 20H19ZM5 15.3368C5.45463 15.1208 5.9632 15 6.5 15H19V4H6C5.44772 4 5 4.44772 5 5V15.3368Z"></path></svg>
|
||||||
|
Songbook
|
||||||
|
</a>
|
||||||
|
<a href="{{ config.extra.git_repository }}" target="_blank" class="button">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M7.10508 15.2101C8.21506 15.6501 9 16.7334 9 18C9 19.6569 7.65685 21 6 21C4.34315 21 3 19.6569 3 18C3 16.6938 3.83481 15.5825 5 15.1707V8.82929C3.83481 8.41746 3 7.30622 3 6C3 4.34315 4.34315 3 6 3C7.65685 3 9 4.34315 9 6C9 7.30622 8.16519 8.41746 7 8.82929V11.9996C7.83566 11.3719 8.87439 11 10 11H14C15.3835 11 16.5482 10.0635 16.8949 8.78991C15.7849 8.34988 15 7.26661 15 6C15 4.34315 16.3431 3 18 3C19.6569 3 21 4.34315 21 6C21 7.3332 20.1303 8.46329 18.9274 8.85392C18.5222 11.2085 16.4703 13 14 13H10C8.61653 13 7.45179 13.9365 7.10508 15.2101ZM6 17C5.44772 17 5 17.4477 5 18C5 18.5523 5.44772 19 6 19C6.55228 19 7 18.5523 7 18C7 17.4477 6.55228 17 6 17ZM6 5C5.44772 5 5 5.44772 5 6C5 6.55228 5.44772 7 6 7C6.55228 7 7 6.55228 7 6C7 5.44772 6.55228 5 6 5ZM18 5C17.4477 5 17 5.44772 17 6C17 6.55228 17.4477 7 18 7C18.5523 7 19 6.55228 19 6C19 5.44772 18.5523 5 18 5Z"></path></svg>
|
||||||
|
Source Code
|
||||||
|
</a>
|
||||||
|
<div class="button">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 7H13V9H11V7ZM11 11H13V17H11V11Z"></path></svg>
|
||||||
|
About
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
<section class="filters">
|
||||||
|
<form>
|
||||||
|
<input type="search" placeholder="Hledat">
|
||||||
|
<input type="reset" value="">
|
||||||
|
</form>
|
||||||
|
<div class="button" data-category="classic">Classic</div>
|
||||||
|
<div class="button" data-category="mixtape">Mixtape</div>
|
||||||
|
</section>
|
||||||
|
<section class="song-list">
|
||||||
|
{% for song in section.pages %}
|
||||||
|
<div class="{{ macros::primary_category(song=song) }}"
|
||||||
|
data-title="{{ song.title }}"
|
||||||
|
data-category="{{ macros::primary_category(song=song) }}"
|
||||||
|
{% if song.taxonomies["artist"] %}
|
||||||
|
data-artist="{{ song.taxonomies["artist"][0] }}"
|
||||||
|
{% endif %}
|
||||||
|
>
|
||||||
|
<div class="meta">
|
||||||
|
<div class="title">{{ song.title }}</div>
|
||||||
|
{% if song.taxonomies["artist"] %}
|
||||||
|
<div class="artist">{{ song.taxonomies["artist"][0] }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="links">
|
||||||
|
<a href="{{ song.permalink }}" class="html"></a>
|
||||||
|
{% for asset in song.assets %}
|
||||||
|
{% if asset is matching(song.slug~"[.](pdf)$") %}
|
||||||
|
<a href="{{ asset }}" class="pdf"></a>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
||||||
|
{% block script %}
|
||||||
|
<script src="{{ get_url(path="/js/filter.js") }}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
5
templates/macros.html
Normal file
5
templates/macros.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{% macro primary_category(song) %}
|
||||||
|
{%- if song.taxonomies["category"] -%}
|
||||||
|
{{ song.taxonomies["category"][0] }}
|
||||||
|
{%- endif -%}
|
||||||
|
{% endmacro %}
|
||||||
32
templates/song.html
Normal file
32
templates/song.html
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{% extends "index.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<main class="song">
|
||||||
|
{% for asset in page.assets %}
|
||||||
|
{% if asset is matching(page.slug~"[.](html)$") %}
|
||||||
|
<iframe class="song" src="{{ asset }}"></iframe>
|
||||||
|
<nav class="controls hidden">
|
||||||
|
<section class="font-size">
|
||||||
|
<div class="button icon-subtract" id="font-size-decrease"></div>
|
||||||
|
<div class="button icon-font-size" id="font-size-reset"></div>
|
||||||
|
<div class="button icon-add" id="font-size-increase"></div>
|
||||||
|
</section>
|
||||||
|
<!--<section class="transpose">-->
|
||||||
|
<!-- <div class="button icon-subtract" id="transpose-decrease"></div>-->
|
||||||
|
<!-- <div class="button icon-transpose" id="transpose-reset"></div>-->
|
||||||
|
<!-- <div class="button icon-add" id="transpose-increase"></div>-->
|
||||||
|
<!--</section>-->
|
||||||
|
<section class="autoscroll">
|
||||||
|
<div class="button icon-subtract" id="autoscroll-decrease"></div>
|
||||||
|
<div class="button icon-scroll" id="autoscroll"></div>
|
||||||
|
<div class="button icon-add" id="autoscroll-increase"></div>
|
||||||
|
</section>
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
<script src="{{ get_url(path="/js/song-controls.js") }}"></script>
|
||||||
|
{% endblock %}
|
||||||
0
templates/taxonomy_list.html
Normal file
0
templates/taxonomy_list.html
Normal file
0
templates/taxonomy_single.html
Normal file
0
templates/taxonomy_single.html
Normal file
Reference in New Issue
Block a user