m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMarcin Chrzanowski <m@m-chrzan.xyz>2021-09-12 14:17:19 +0200
committerMarcin Chrzanowski <m@m-chrzan.xyz>2021-09-12 14:17:19 +0200
commitf3039744d72454e7e3b8cb1032266bcc172ce488 (patch)
tree5a92a698056e2cbec6f0b121a9ce31596e4a4581 /lib
Initial commit
Diffstat (limited to 'lib')
-rw-r--r--lib/html.rb13
-rw-r--r--lib/latex.rb17
-rw-r--r--lib/ly.rb14
-rw-r--r--lib/pather.rb39
-rw-r--r--lib/recording.rb36
-rw-r--r--lib/song.rb47
-rw-r--r--lib/songs.rb19
-rw-r--r--lib/statics.rb10
-rw-r--r--lib/templated.rb20
-rw-r--r--lib/util.rb85
10 files changed, 300 insertions, 0 deletions
diff --git a/lib/html.rb b/lib/html.rb
new file mode 100644
index 0000000..61e25a3
--- /dev/null
+++ b/lib/html.rb
@@ -0,0 +1,13 @@
+require './lib/templated'
+
+def render_html song
+ template = html_template 'song'
+ template.result binding
+end
+
+def make_htmls songs
+ songs.each do |song_id, song|
+ content = render_html song
+ write_templated content, song_html(song_id), song.title
+ end
+end
diff --git a/lib/latex.rb b/lib/latex.rb
new file mode 100644
index 0000000..e17a6ef
--- /dev/null
+++ b/lib/latex.rb
@@ -0,0 +1,17 @@
+def render_latex song
+ template = tex_template 'song'
+ templated = template.result binding
+ File.write(tmp(song_tex song.id), templated)
+end
+
+def render_pdf song
+ render_latex song
+ system "lualatex --shell-escape -output-directory=#{TmpDir}/#{SongsDir} #{tmp (song_tex song.id)}"
+ system "mv #{tmp (song_pdf song.id)} #{build (song_pdf song.id)}"
+end
+
+def make_pdfs songs
+ songs.each_value do |song|
+ render_pdf song
+ end
+end
diff --git a/lib/ly.rb b/lib/ly.rb
new file mode 100644
index 0000000..fc85204
--- /dev/null
+++ b/lib/ly.rb
@@ -0,0 +1,14 @@
+def compile_ly ly_filename
+ system "lilypond --svg --output=#{tmp SongsDir} #{ly_filename}"
+ system "lilypond --output=#{tmp SongsDir} #{ly_filename}"
+end
+
+def make_sheets songs
+ songs.keys.each do |song_id|
+ ly_filename = src(song_ly song_id)
+ if File.file? ly_filename
+ compile_ly ly_filename
+ system "mv #{tmp (song_tmp_svg song_id)} #{build(song_svg song_id)}"
+ end
+ end
+end
diff --git a/lib/pather.rb b/lib/pather.rb
new file mode 100644
index 0000000..1f59df0
--- /dev/null
+++ b/lib/pather.rb
@@ -0,0 +1,39 @@
+class Pather
+ attr_accessor :current_path
+ def initialize
+ @assets = {}
+ @current_path = []
+ end
+
+ def add asset_id, path
+ @assets[asset_id] = @current_path + path.split('/')
+ end
+
+ def path_to asset_id
+ other_path = @assets[asset_id]
+ find_path_between @current_path, other_path
+ end
+
+ def find_path_between from, to
+ from, to = drop_common_prefix from, to
+ path = ('../' * from.length) + to.join('/')
+ end
+
+ def drop_common_prefix path1, path2
+ common_prefix_length = path1.zip(path2).take_while do |(segment1, segment2)|
+ segment1 == segment2
+ end.length
+
+ return path1[common_prefix_length..], path2[common_prefix_length..]
+ end
+
+ def cd path
+ path.split('/').each do |segment|
+ if segment == '..'
+ @current_path.pop
+ else
+ @current_path.push segment
+ end
+ end
+ end
+end
diff --git a/lib/recording.rb b/lib/recording.rb
new file mode 100644
index 0000000..d1d7683
--- /dev/null
+++ b/lib/recording.rb
@@ -0,0 +1,36 @@
+class NotImplemented < Exception
+end
+
+class Recording
+ def render
+ raise NotImplemented
+ end
+end
+
+class YouTubeRecording
+ attr_accessor :vid
+ def initialize link
+ @vid = parse_vid link
+ end
+
+ def parse_vid link
+ /\?v=(.{11})/.match(link)[1]
+ end
+
+ def render
+ template = ERB.new(File.read('templates/youtube.html.erb'), trim_mode: '-')
+ template.result binding
+ end
+end
+
+class BandcampRecording
+ attr_accessor :link
+ def initialize link
+ @link = link
+ end
+
+ def render
+ template = ERB.new(File.read('templates/bandcamp.html.erb'), trim_mode: '-')
+ template.result binding
+ end
+end
diff --git a/lib/song.rb b/lib/song.rb
new file mode 100644
index 0000000..4076956
--- /dev/null
+++ b/lib/song.rb
@@ -0,0 +1,47 @@
+require 'yaml'
+
+require './lib/recording'
+
+class Song
+ attr_accessor :title, :id, :lyrics, :recordings
+ def initialize title, id
+ @title = title
+ @id = id
+ @recordings = []
+ end
+
+ def self.from_yaml song_id
+ metadata = YAML.load(File.read(src(song_meta song_id)))
+ song = Song.new metadata['title'], song_id
+
+ song.lyrics = nil
+ lyrics_file = src (song_lyrics song_id)
+ if File.file? lyrics_file
+ song.lyrics = File.read lyrics_file
+ end
+
+ if metadata['recordings']
+ metadata['recordings'].each do |recording|
+ if recording['type'] == 'youtube'
+ song.recordings.push YouTubeRecording.new(recording['link'])
+ elsif recording['type'] == 'bandcamp'
+ song.recordings.push BandcampRecording.new(recording['link'])
+ end
+ end
+ end
+ song
+ end
+
+ def split_lyrics
+ @lyrics.split("\n\n").map { |paragraph| paragraph.split "\n" }
+ end
+
+ def render_sheet_music
+ if File.file? (src (song_ly id))
+ template = ERB.new(File.read('templates/sheet_music.html.erb'), trim_mode: '-')
+ template.result binding
+ else
+ ""
+ end
+ end
+end
diff --git a/lib/songs.rb b/lib/songs.rb
new file mode 100644
index 0000000..aa519e1
--- /dev/null
+++ b/lib/songs.rb
@@ -0,0 +1,19 @@
+require 'set'
+
+require './lib/util'
+
+@songs = nil
+
+def get_song_ids dir
+ ids = Set.new
+ Dir.new(src SongsDir).children.each do |filename|
+ ids.add(File.basename filename, '.*')
+ end
+ ids
+end
+
+def songs
+ @songs ||= get_song_ids(SongsDir).map do |song_id|
+ [song_id, Song.from_yaml(song_id)]
+ end.to_h
+end
diff --git a/lib/statics.rb b/lib/statics.rb
new file mode 100644
index 0000000..24ca9d6
--- /dev/null
+++ b/lib/statics.rb
@@ -0,0 +1,10 @@
+require 'fileutils'
+
+def write_statics statics
+ statics = statics.each do |filename|
+ source = src filename
+ target = build filename
+ FileUtils.mkdir_p(File.dirname target)
+ FileUtils.cp_r source, target
+ end
+end
diff --git a/lib/templated.rb b/lib/templated.rb
new file mode 100644
index 0000000..548352c
--- /dev/null
+++ b/lib/templated.rb
@@ -0,0 +1,20 @@
+def write_templated_file content_filename, title
+ content = File.read(src content_filename)
+ write_templated content, content_filename, title
+end
+
+def write_erb erb_filename
+ content = ERB.new(File.read(src erb_filename)).result
+ cut_filename = erb_filename.sub /\.erb$/, ''
+ File.write build(cut_filename), content
+end
+
+def write_templated_erb erb_filename, title = nil
+ content = ERB.new(File.read(src erb_filename), trim_mode: '-').result
+ cut_filename = erb_filename.sub /\.erb$/, ''
+ write_templated content, cut_filename, title
+end
+
+def write_templated content, filename, title = nil
+ File.write build(filename), page_template.result(binding)
+end
diff --git a/lib/util.rb b/lib/util.rb
new file mode 100644
index 0000000..48698ff
--- /dev/null
+++ b/lib/util.rb
@@ -0,0 +1,85 @@
+SongsDir = 'songs'
+SrcDir = 'src'
+BuildDir = 'public'
+TmpDir = 'tmp'
+TemplatesDir = 'templates'
+
+def song filename
+ File.join SongsDir, filename
+end
+
+def build filename
+ File.join BuildDir, filename
+end
+
+def tmp filename
+ File.join TmpDir, filename
+end
+
+def src filename
+ File.join SrcDir, filename
+end
+
+def song_lyrics song_id
+ song "#{song_id}.txt"
+end
+
+def song_ly song_id
+ song "#{song_id}.ly"
+end
+
+def song_meta song_id
+ song "#{song_id}.yaml"
+end
+
+def song_tex song_id
+ song "#{song_id}.tex"
+end
+
+def song_sheet_pdf song_id
+ song "#{song_id}.cropped.pdf"
+end
+
+def song_tmp_svg song_id
+ song "#{song_id}.cropped.svg"
+end
+
+def song_pdf song_id
+ song "#{song_id}.pdf"
+end
+
+def song_sheet_svg song_id
+ song "#{song_id}.svg"
+end
+
+def song_svg song_id
+ song "#{song_id}.svg"
+end
+
+def song_html song_id
+ song "#{song_id}.html"
+end
+
+def template filename
+ ERB.new(File.read(filename), trim_mode: '-')
+end
+
+def template_file filename
+ File.join TemplatesDir, filename
+end
+
+def tex_template name
+ template(template_file "#{name}.tex.erb")
+end
+
+def html_template name
+ template(template_file "#{name}.html.erb")
+end
+
+def page_template
+ html_template 'template'
+end
+
+def path_to asset_id
+ P.path_to asset_id
+end