mirror of
https://gitlab.com/parroquia-san-leandro/cancionero-web.git
synced 2026-01-28 13:07:58 +01:00
Página preparar-misa.html y fragmentos de canciones
This commit is contained in:
parent
c622a27e34
commit
434cbc1c25
10 changed files with 391 additions and 21 deletions
|
|
@ -67,7 +67,7 @@ div.chorus, p.chorus {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
button, select#transposeSelect {
|
button, select.transposeSelect {
|
||||||
min-width: 2em;
|
min-width: 2em;
|
||||||
min-height: 2em;
|
min-height: 2em;
|
||||||
padding: .4em;
|
padding: .4em;
|
||||||
|
|
@ -88,7 +88,7 @@ button, select#transposeSelect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
select#transposeSelect {
|
select.transposeSelect {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ function size(steps) {
|
||||||
currSize = SIZE_STEPS.indexOf(100);
|
currSize = SIZE_STEPS.indexOf(100);
|
||||||
}
|
}
|
||||||
currSize += steps;
|
currSize += steps;
|
||||||
document.getElementById('wholeSongDiv').style.fontSize = SIZE_STEPS[currSize] + '%';
|
for (let div of document.getElementsByClassName('fullsong'))
|
||||||
|
div.style.fontSize = SIZE_STEPS[currSize] + '%';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================
|
/* ===========================================
|
||||||
|
|
@ -25,13 +26,18 @@ CHORDS_ENG = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'Bb', 'B']
|
||||||
|
|
||||||
|
|
||||||
/** Changes all chords to a given semitone relative to the original */
|
/** Changes all chords to a given semitone relative to the original */
|
||||||
function transpose(n) {
|
function transpose(n, song) {
|
||||||
transposeAdd(n - getTranspose())
|
transposeAdd(n - getTranspose(song), song)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Transposes all chords by n steps */
|
/** Transposes all chords by n steps */
|
||||||
function transposeAdd(n) {
|
function transposeAdd(n, song) { // TODO use song!
|
||||||
for (c of document.getElementsByClassName('c')) {
|
let div;
|
||||||
|
if (song)
|
||||||
|
div = document.getElementById("song" + song);
|
||||||
|
else
|
||||||
|
div = document.getElementsByClassName("fullsong")[0];
|
||||||
|
for (c of div.getElementsByClassName('c')) {
|
||||||
chord = c.innerHTML
|
chord = c.innerHTML
|
||||||
nbsp = chord.endsWith(" ")
|
nbsp = chord.endsWith(" ")
|
||||||
if (nbsp) {
|
if (nbsp) {
|
||||||
|
|
@ -45,17 +51,21 @@ function transposeAdd(n) {
|
||||||
c.innerHTML = CHORDS_LAT[j] + (nbsp ? " " : "")
|
c.innerHTML = CHORDS_LAT[j] + (nbsp ? " " : "")
|
||||||
}
|
}
|
||||||
|
|
||||||
setTransposeSelector(getTranspose() + n)
|
setTransposeSelector(getTranspose(song) + n, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTransposeSelector(n) {
|
function setTransposeSelector(n, song) {
|
||||||
while (n > 6) {
|
while (n > 6) {
|
||||||
n -= 12
|
n -= 12
|
||||||
}
|
}
|
||||||
while (n < -6) {
|
while (n < -6) {
|
||||||
n += 12
|
n += 12
|
||||||
}
|
}
|
||||||
ts = document.getElementById("transposeSelect")
|
let ts;
|
||||||
|
if (song)
|
||||||
|
ts = document.getElementById("transposeSelect" + song);
|
||||||
|
else
|
||||||
|
ts = document.getElementById("transposeSelect");
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
ts.value = "+" + n
|
ts.value = "+" + n
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -63,7 +73,9 @@ function setTransposeSelector(n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTranspose() {
|
function getTranspose(song) {
|
||||||
|
if (song)
|
||||||
|
return Number.parseInt(document.getElementById("transposeSelect" + song).value)
|
||||||
return Number.parseInt(document.getElementById("transposeSelect").value)
|
return Number.parseInt(document.getElementById("transposeSelect").value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
<li><a href="https://sanleandrovalencia.es/"><span id="nav-web">Parroquia San Leandro</span></a></li>
|
<li><a href="https://sanleandrovalencia.es/"><span id="nav-web">Parroquia San Leandro</span></a></li>
|
||||||
<li><a href="https://nube.sanleandrovalencia.es/s/X23Jzz5A6dpCfr2"><span id="nav-audios">Grabaciones</span></a></li>
|
<li><a href="https://nube.sanleandrovalencia.es/s/X23Jzz5A6dpCfr2"><span id="nav-audios">Grabaciones</span></a></li>
|
||||||
<li><a href="https://sanleandrovalencia.es/cancionero/"><span>Cancionero en PDF</span></a></li>
|
<li><a href="https://sanleandrovalencia.es/cancionero/"><span>Cancionero en PDF</span></a></li>
|
||||||
|
<li><a href="{{ path }}/preparar-misa.html"><span>Preparar misa</span></a></li>
|
||||||
|
<li><a href="{{ path }}/cuando-entrar/"><span>¿Cuándo se entra?</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
||||||
204
res/templates/preparar-misa.html
Normal file
204
res/templates/preparar-misa.html
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="es">
|
||||||
|
<head>
|
||||||
|
{% include "head.html" with path=path title=title only %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ path|urlencode }}/index.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ path|urlencode }}/song.css">
|
||||||
|
<script src="{{ path|urlencode }}/song.js"></script>
|
||||||
|
<style>
|
||||||
|
.hideControls .controls {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.hidePreview .preview {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "header.html" %}
|
||||||
|
<main>
|
||||||
|
<h1>Preparar una misa</h1>
|
||||||
|
<p>A continuación puedes crear una web con una lista de canciones y
|
||||||
|
<input type="button" onclick="shareList(event)" value="compartirla">.</p>
|
||||||
|
<p>Si prefieres crear un PDF, <a href="https://cgj.es/cancionero-generador/">pulsa aquí</a>.</p>
|
||||||
|
<p>
|
||||||
|
<label><input class="init" id="controlsCheckbox" type="checkbox" onchange="toggleControls(event)" checked> Modificar la lista</label>
|
||||||
|
<label><input class="init" id="previewCheckbox" type="checkbox" onchange="togglePreview(event)"> Ver las canciones</label>
|
||||||
|
<label><input id="showChords" type="checkbox" checked onchange="showChords(this.checked)"/> Mostrar acordes</label>
|
||||||
|
</p>
|
||||||
|
<p class="controls">
|
||||||
|
<input type="button" value="Borrar todas" onclick="clearSongs()">
|
||||||
|
<input type="button" value="Añadir canción" onclick="addSong()">
|
||||||
|
<input type="button" value="Añadir canción aleatoria" onclick="addRandomSong()">
|
||||||
|
<input type="button" value="Añadir la primera canción de cada sección" onclick="addFirstSongs()">
|
||||||
|
<input type="button" value="Añadir una canción por sección (aleatorias)" onclick="addRandomSongs()">
|
||||||
|
</p>
|
||||||
|
<ul id="songlist"></ul>
|
||||||
|
<input type="button" onclick="shareList(event)" value="Compartir enlace al cancionero">
|
||||||
|
<dialog id="sharedialog">
|
||||||
|
<p>Copia y comparte el enlace: <a id="sharelink" href="">tus canciones</a></p>
|
||||||
|
<input type="button" onclick="event.target.parentElement.close()" value="Cerrar">
|
||||||
|
</dialog>
|
||||||
|
<template id='songtemplate'>
|
||||||
|
<li><span class="controls"><select name="songs[]" required onchange="songSelect(event)">
|
||||||
|
<option value="">Selecciona una canción</option>{% for category, songs in categorized_songs %}
|
||||||
|
<optgroup label="— {{ category }}">{% for s in songs %}
|
||||||
|
<option value="{{ s.number }}">{{ s.number }}. {{ s.name }}</option>{% endfor %}
|
||||||
|
</optgroup>{% endfor %}
|
||||||
|
</select>
|
||||||
|
<input type="button" value="Subir" onclick="songUp(event)">
|
||||||
|
<input type="button" value="Bajar" onclick="songDown(event)">
|
||||||
|
<input type="button" value="Quitar" onclick="songDelete(event)"></span>
|
||||||
|
<div class="preview"></div>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</main>
|
||||||
|
<script>
|
||||||
|
function addSong() {
|
||||||
|
let ol = document.getElementById("songlist");
|
||||||
|
let node = document.getElementById("songtemplate").content.firstElementChild.cloneNode(true);
|
||||||
|
ol.appendChild(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function songUp(event) {
|
||||||
|
const li = event.target.parentElement.parentElement;
|
||||||
|
const prev = li.previousElementSibling;
|
||||||
|
const ol = li.parentElement;
|
||||||
|
if (prev)
|
||||||
|
ol.insertBefore(li, prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
function songDown(event) {
|
||||||
|
const li = event.target.parentElement.parentElement;
|
||||||
|
const next = li.nextElementSibling;
|
||||||
|
const after = next?.nextElementSibling;
|
||||||
|
const ol = li.parentElement;
|
||||||
|
if (after)
|
||||||
|
ol.insertBefore(li, after);
|
||||||
|
else if (next)
|
||||||
|
ol.appendChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
function songDelete(event) {
|
||||||
|
const li = event.target.parentElement.parentElement;
|
||||||
|
const ol = li.parentElement;
|
||||||
|
ol.removeChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
function songSelect(event) {
|
||||||
|
const option = event.target.selectedOptions[0];
|
||||||
|
const div = event.target.parentElement.parentElement.getElementsByClassName("preview")[0];
|
||||||
|
if (option.value) {
|
||||||
|
fetch("./{{ parts_dir }}/" + String(option.value).padStart(3, '0') + ".html")
|
||||||
|
.then(r => r.text())
|
||||||
|
.then(text => div.innerHTML = text);
|
||||||
|
} else {
|
||||||
|
div.innerHTML = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSongs() {
|
||||||
|
const ol = document.getElementById("songlist");
|
||||||
|
ol.replaceChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectRandomizeOptions(select, optionParent) {
|
||||||
|
const options = optionParent.getElementsByTagName("option");
|
||||||
|
do {
|
||||||
|
const i = Math.floor(Math.random() * options.length);
|
||||||
|
select.value = options[i].value;
|
||||||
|
} while (!select.value);
|
||||||
|
select.dispatchEvent(new Event("change"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSpecificSong(n) {
|
||||||
|
const li = addSong();
|
||||||
|
const select = li.firstElementChild.firstElementChild;
|
||||||
|
select.value = n;
|
||||||
|
select.dispatchEvent(new Event("change"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function addRandomSong() {
|
||||||
|
const li = addSong();
|
||||||
|
const select = li.firstElementChild.firstElementChild;
|
||||||
|
selectRandomizeOptions(select, select);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addFirstSongs() {
|
||||||
|
addSongs(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addRandomSongs() {
|
||||||
|
addSongs(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSongs(random) {
|
||||||
|
const li = addSong();
|
||||||
|
const groups = li.firstElementChild.firstElementChild.getElementsByTagName("optgroup");
|
||||||
|
for (let g of groups) {
|
||||||
|
const select = addSong().firstElementChild.firstElementChild;
|
||||||
|
if (random) {
|
||||||
|
selectRandomizeOptions(select, g);
|
||||||
|
} else {
|
||||||
|
select.value = g.firstElementChild.value;
|
||||||
|
select.dispatchEvent(new Event("change"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
li.parentElement.removeChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleControls(event) {
|
||||||
|
if (event.target.checked)
|
||||||
|
document.body.classList.remove("hideControls");
|
||||||
|
else
|
||||||
|
document.body.classList.add("hideControls");
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePreview(event) {
|
||||||
|
if (event.target.checked)
|
||||||
|
document.body.classList.remove("hidePreview");
|
||||||
|
else
|
||||||
|
document.body.classList.add("hidePreview");
|
||||||
|
}
|
||||||
|
|
||||||
|
function shareList(event) {
|
||||||
|
const ol = document.getElementById("songlist");
|
||||||
|
let res = [];
|
||||||
|
for (let li of ol.childNodes) {
|
||||||
|
let song = li.firstElementChild.firstElementChild.value;
|
||||||
|
res.push(song);
|
||||||
|
}
|
||||||
|
if (res.length > 0) {
|
||||||
|
let hash = res.join(",");
|
||||||
|
document.getElementById("sharelink").href = "#" + hash;
|
||||||
|
document.getElementById("sharedialog").showModal();
|
||||||
|
} else {
|
||||||
|
alert("Tu cancionero no tiene canciones...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function () {
|
||||||
|
for (let e of document.getElementsByClassName("init")) {
|
||||||
|
e.dispatchEvent(new Event("change"));
|
||||||
|
}
|
||||||
|
if (window.location.hash) {
|
||||||
|
// Load songs
|
||||||
|
for (let n of window.location.hash.slice(1).split(","))
|
||||||
|
addSpecificSong(n);
|
||||||
|
// Set default settings
|
||||||
|
let controls = document.getElementById("controlsCheckbox");
|
||||||
|
controls.checked = false;
|
||||||
|
controls.dispatchEvent(new Event("change"));
|
||||||
|
let preview = document.getElementById("previewCheckbox");
|
||||||
|
preview.checked = true;
|
||||||
|
preview.dispatchEvent(new Event("change"));
|
||||||
|
let showChords = document.getElementById("showChords");
|
||||||
|
showChords.checked = false;
|
||||||
|
showChords.dispatchEvent(new Event("change"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
{% include "footer.html" %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
<label for="transposeSelect">Transponer acordes </label>
|
<label for="transposeSelect">Transponer acordes </label>
|
||||||
<button class="small" onclick="transposeAdd(-2)">-2</button>
|
<button class="small" onclick="transposeAdd(-2)">-2</button>
|
||||||
<button class="small" onclick="transposeAdd(-1)">-1</button>
|
<button class="small" onclick="transposeAdd(-1)">-1</button>
|
||||||
<select id="transposeSelect" disabled>
|
<select id="transposeSelect" class="transposeSelect" disabled>
|
||||||
<option>-6</option>
|
<option>-6</option>
|
||||||
<option>-5</option>
|
<option>-5</option>
|
||||||
<option>-4</option>
|
<option>-4</option>
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h3>Canción</h3>
|
<h3>Canción</h3>
|
||||||
<div id="wholeSongDiv">
|
<div class="fullsong">
|
||||||
<div id="songLyrics" class="showLyrics" style="display: none;">
|
<div id="songLyrics" class="showLyrics" style="display: none;">
|
||||||
{% for verse in song.verses %}
|
{% for verse in song.verses %}
|
||||||
<p class="{{ verse.kind }}">
|
<p class="{{ verse.kind }}">
|
||||||
|
|
|
||||||
126
res/templates/song_fragment.html
Normal file
126
res/templates/song_fragment.html
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
<div class="song" id="song{{song.number}}">
|
||||||
|
<h2 style="display: inline-block;">{{song.number}}. {{ song.name}}</h2>
|
||||||
|
{% if song.author %}
|
||||||
|
<span>por <strong>{{ song.author }}</strong></span>
|
||||||
|
{% endif %}
|
||||||
|
{% if song.origin %}
|
||||||
|
<span>basada en: <strong>{{ song.origin }}</strong></span>
|
||||||
|
{% endif %}
|
||||||
|
{% if song.chorded %}
|
||||||
|
<div class="showChords chordControls">
|
||||||
|
<label for="transposeSelect{{ song.number }}">Tono {% spaceless %}
|
||||||
|
{% with chord=song.first_chord %}
|
||||||
|
{% if chord %}
|
||||||
|
<span class="chord">{% for c in chord.items_t %}
|
||||||
|
{% if c.chord %}
|
||||||
|
<span class="c">{{ c.text|safe }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span>{{ c.text|safe }}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}</span>
|
||||||
|
{% endif %}{% endwith %}{% endspaceless %}</label>
|
||||||
|
<button class="small" onclick="transposeAdd(-1, {{song.number}})">-1</button>
|
||||||
|
<select id="transposeSelect{{ song.number }}" class="transposeSelect" disabled>
|
||||||
|
<option>-6</option>
|
||||||
|
<option>-5</option>
|
||||||
|
<option>-4</option>
|
||||||
|
<option>-3</option>
|
||||||
|
<option>-2</option>
|
||||||
|
<option>-1</option>
|
||||||
|
<option selected="selected">0</option>
|
||||||
|
<option>+1</option>
|
||||||
|
<option>+2</option>
|
||||||
|
<option>+3</option>
|
||||||
|
<option>+4</option>
|
||||||
|
<option>+5</option>
|
||||||
|
<option>+6</option>
|
||||||
|
</select>
|
||||||
|
<button class="small" onclick="transposeAdd(1, {{song.number}})">+1</button>
|
||||||
|
<button onclick="transpose(0, {{song.number}})">Reset</button>
|
||||||
|
</div>
|
||||||
|
{% if song.capo != 0 %}
|
||||||
|
<div class="showChords">
|
||||||
|
<span class="capo">Tono original: Cejilla {{ song.capo }}</span>
|
||||||
|
<button style="margin-left: 0.5em;" onclick="transpose({{ song.capo}}, {{song.number}})">Transponer para quitarla</button>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<div class="fullsong">
|
||||||
|
<div class="showLyrics" style="display: none;">
|
||||||
|
{% for verse in song.verses %}
|
||||||
|
<p class="{{ verse.kind }}">
|
||||||
|
{% for line in verse.lines %}
|
||||||
|
{{ line }}<br/>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="showChords">
|
||||||
|
{% for verse in song.verses %}
|
||||||
|
<div class="{{ verse.kind }}">
|
||||||
|
{% for line in verse.lines %}
|
||||||
|
{% spaceless %}
|
||||||
|
{% for chord, lyric in line.zipped_arr %}
|
||||||
|
<table class="chordedline">
|
||||||
|
<tr class="chord">
|
||||||
|
<td rowspan="{{ chord.rowspan|default:'1' }}">
|
||||||
|
{% if chord.class %}
|
||||||
|
<span class="{{ chord.class }}"></span>
|
||||||
|
{% endif %}
|
||||||
|
{% if chord.chord.trfmt == "normal" %}
|
||||||
|
{% for c in chord.chord.items_t %}
|
||||||
|
{% if c.chord %}
|
||||||
|
<span class="c">{{ c.text|safe }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span>{{ c.text|safe }}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if chord.chord.trfmt == "double" %}
|
||||||
|
<span>
|
||||||
|
{% for c in chord.chord.items_n %}
|
||||||
|
{% if c.chord %}
|
||||||
|
<span class="c">{{ c.text|safe }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span>{{ c.text|safe }}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<br/>
|
||||||
|
{% for c in chord.chord.items_t %}
|
||||||
|
{% if c.chord %}
|
||||||
|
<span class="c">{{ c.text|safe }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span>{{ c.text|safe }}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<span/>
|
||||||
|
{% endif %}
|
||||||
|
{% if chord.chord.trfmt == "hover" %}
|
||||||
|
<span>
|
||||||
|
{% for c in chord.chord.items_n %}
|
||||||
|
{% if c.chord %}
|
||||||
|
<span class="c">{{ c.text|safe }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span>{{ c.text|safe }}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<br/> </span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="lyric">
|
||||||
|
<td>
|
||||||
|
{% if 'rowspan' not in chord %}
|
||||||
|
<span>{{ lyric|safe }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{% endfor %}
|
||||||
|
{% if not forloop.last %} <br/> {% endif %}
|
||||||
|
{% endspaceless %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ol>
|
</ol>
|
||||||
{% for song in songs %}
|
{% for song in songs %}
|
||||||
<div class="song" id="wholeSongDiv">
|
<div class="song" id="fullsong">
|
||||||
<h2 id="{{ song.number }}">{{ song.number }}. {{ song.name }}</h2>
|
<h2 id="{{ song.number }}">{{ song.number }}. {{ song.name }}</h2>
|
||||||
<div id="songLyrics">
|
<div id="songLyrics">
|
||||||
{% for verse in song.verses %}
|
{% for verse in song.verses %}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import latex_scanner
|
from latex_scanner import create_argparser, SongLoader, categorize_songs
|
||||||
from os.path import join
|
from os.path import join
|
||||||
from django.template import Engine, Context
|
from django.template import Engine, Context
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
@ -16,9 +16,7 @@ def create_generator(songs, out_dir, dj_engine):
|
||||||
else:
|
else:
|
||||||
remove.add(song.latex_file)
|
remove.add(song.latex_file)
|
||||||
selected_songs = [s for s in songs if s.latex_file not in remove]
|
selected_songs = [s for s in songs if s.latex_file not in remove]
|
||||||
category_set = set(s.category for s in selected_songs)
|
dictionary = categorize_songs(selected_songs)
|
||||||
categories = sorted(category_set, key=lambda c:min([s.number for s in songs if s.category == c]))
|
|
||||||
dictionary = [(c, [s for s in selected_songs if s.category == c]) for c in categories]
|
|
||||||
|
|
||||||
|
|
||||||
# Export to html
|
# Export to html
|
||||||
|
|
@ -29,7 +27,7 @@ def create_generator(songs, out_dir, dj_engine):
|
||||||
|
|
||||||
def create_argparser():
|
def create_argparser():
|
||||||
'''Parse main's arguments.'''
|
'''Parse main's arguments.'''
|
||||||
parser = latex_scanner.create_argparser()
|
parser = create_argparser()
|
||||||
parser.add_argument("--generator-dir", required=False, nargs=1, default=["generador_public"],
|
parser.add_argument("--generator-dir", required=False, nargs=1, default=["generador_public"],
|
||||||
help="The path where the generated files should be placed.")
|
help="The path where the generated files should be placed.")
|
||||||
return parser
|
return parser
|
||||||
|
|
@ -41,7 +39,7 @@ if __name__ == '__main__':
|
||||||
with open("songs.dat", "rb") as f:
|
with open("songs.dat", "rb") as f:
|
||||||
songs = pickle.load(f)
|
songs = pickle.load(f)
|
||||||
except OSError:
|
except OSError:
|
||||||
loader = latex_scanner.SongLoader(args.latex[0])
|
loader = SongLoader(args.latex[0])
|
||||||
if args.other_latex:
|
if args.other_latex:
|
||||||
loader.scan_others(args.other_latex[0], args.other_index[0])
|
loader.scan_others(args.other_latex[0], args.other_index[0])
|
||||||
songs = loader.songs
|
songs = loader.songs
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,12 @@ def mkdir(path: str) -> None:
|
||||||
# Note that re.match prepends ^ to the pattern, whereas re.search doesn't
|
# Note that re.match prepends ^ to the pattern, whereas re.search doesn't
|
||||||
|
|
||||||
|
|
||||||
|
def categorize_songs(songs):
|
||||||
|
category_set = set(s.category for s in songs)
|
||||||
|
categories = sorted(category_set, key=lambda c:min([s.number for s in songs if s.category == c]))
|
||||||
|
return [(c, [s for s in songs if s.category == c]) for c in categories]
|
||||||
|
|
||||||
|
|
||||||
def read_property(text: str, key: str) -> str | None:
|
def read_property(text: str, key: str) -> str | None:
|
||||||
'''A parser for \\beginsong attributes.'''
|
'''A parser for \\beginsong attributes.'''
|
||||||
if text is None:
|
if text is None:
|
||||||
|
|
@ -306,11 +312,24 @@ class SongLoader:
|
||||||
with open(join(song_dir, "index.html"), 'w') as f:
|
with open(join(song_dir, "index.html"), 'w') as f:
|
||||||
f.write(dj_engine.get_template("song.html").render(context))
|
f.write(dj_engine.get_template("song.html").render(context))
|
||||||
|
|
||||||
|
def print_song_generator(self, output_dir, parts_dir, dj_engine, metadata):
|
||||||
|
context = Context(dict({ 'path': '.', 'categorized_songs': categorize_songs(self.songs), 'parts_dir': parts_dir}, **metadata))
|
||||||
|
with open(join(output_dir, "preparar-misa.html"), "w") as f:
|
||||||
|
f.write(dj_engine.get_template("preparar-misa.html").render(context))
|
||||||
|
|
||||||
|
song_template = dj_engine.get_template("song_fragment.html")
|
||||||
|
dir = join(output_dir, parts_dir)
|
||||||
|
mkdir(dir)
|
||||||
|
for song in self.songs:
|
||||||
|
with open(join(dir, f"{song.number:03}.html"), "w") as f:
|
||||||
|
f.write(song_template.render(Context({ 'song': song })))
|
||||||
|
|
||||||
def generate_html(self, output_dir, dj_engine, metadata):
|
def generate_html(self, output_dir, dj_engine, metadata):
|
||||||
mkdir(output_dir)
|
mkdir(output_dir)
|
||||||
for song in self.songs:
|
for song in self.songs:
|
||||||
self.print_song(song, output_dir, dj_engine, metadata)
|
self.print_song(song, output_dir, dj_engine, metadata)
|
||||||
self.print_index(join(output_dir, "index.html"), dj_engine, metadata)
|
self.print_index(join(output_dir, "index.html"), dj_engine, metadata)
|
||||||
|
self.print_song_generator(output_dir, "insertable_song", dj_engine, metadata)
|
||||||
|
|
||||||
|
|
||||||
def create_argparser():
|
def create_argparser():
|
||||||
|
|
|
||||||
11
src/model.py
11
src/model.py
|
|
@ -49,6 +49,9 @@ class Song:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def first_chord(self):
|
||||||
|
return next(filter(None, map(Verse.first_chord, self.verses)), None)
|
||||||
|
|
||||||
def has_audios(self):
|
def has_audios(self):
|
||||||
return len(self.audios) > 0
|
return len(self.audios) > 0
|
||||||
|
|
||||||
|
|
@ -72,6 +75,9 @@ class Verse:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def first_chord(self):
|
||||||
|
return next(filter(None, map(Line.first_chord, self.lines)), None)
|
||||||
|
|
||||||
|
|
||||||
class Line:
|
class Line:
|
||||||
ECHO_BEGIN = '<span class="echo">'
|
ECHO_BEGIN = '<span class="echo">'
|
||||||
|
|
@ -85,7 +91,7 @@ class Line:
|
||||||
self.build()
|
self.build()
|
||||||
self.remove_brackets()
|
self.remove_brackets()
|
||||||
assert len(self.chord_arr) == len(self.lyric_arr)
|
assert len(self.chord_arr) == len(self.lyric_arr)
|
||||||
self.zipped_arr = zip(self.chord_arr, self.lyric_arr)
|
self.zipped_arr = list(zip(self.chord_arr, self.lyric_arr))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.text
|
return self.text
|
||||||
|
|
@ -166,6 +172,9 @@ class Line:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def first_chord(self):
|
||||||
|
return next((i["data"] for key in self.extras for i in self.extras[key] if i["type"] == "chord"), None)
|
||||||
|
|
||||||
|
|
||||||
def chord_eng2lat(text, transpose = 0):
|
def chord_eng2lat(text, transpose = 0):
|
||||||
return Chord.CHORDS_LAT[(Chord.ENG_INDEX[text] + transpose + len(Chord.CHORDS_LAT)) % len(Chord.CHORDS_LAT)]
|
return Chord.CHORDS_LAT[(Chord.ENG_INDEX[text] + transpose + len(Chord.CHORDS_LAT)) % len(Chord.CHORDS_LAT)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue