M build.sh +1 -1
@@ 9,7 9,7 @@ fi
if ! test -e Makefile; then ln -s ../MakeStuff/Makefile; fi
for i in *ly; do
- lilypond -dbackend=eps -dno-gs-load-fonts -dinclude-eps-fonts --pdf -o "$(basename "$i" .ly)"-lily $i
+ lilypond -dbackend=eps -dno-gs-load-fonts -dinclude-eps-fonts --pdf -o "$(basename "$i" .ly)" $i
# cannot use pdf as backend with epubli
# gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dCompatibilityLevel=1.3 -dPDFSETTINGS=/printer -dColorImageResolution=600 -dEmbedAllFonts=true -sOutputFile="$(basename "$i" .ly)".pdf "$(basename "$i" .ly)"-lily.pdf
# rm "$(basename "$i" .ly)".pdf
M delfini.flk +1 -1
@@ 4,7 4,7 @@
\subtitle{Für A}
\catcode`\[=12%allow using [ as parameter
-\includegraphics[width=0.96\linewidth, keepaspectratio, trim=0 160cm 0 0]{delfini-tune}% trim, because lilypond creates full-page pngs
+\includegraphics[width=0.96\linewidth, keepaspectratio]{delfini-tune}% trim, because lilypond creates full-page pngs
\catcode`\[=13%force [ to start chords again
\Large
M der-falke.flk +1 -1
@@ 3,7 3,7 @@
\index{Ich zog mir einen Falken}
\subtitle{Für A, wohl von 1160}
\catcode`\[=12%allow using [ as parameter
-\includegraphics[width=0.96\linewidth, keepaspectratio, trim=0 160cm 0 0]{der-falke-tune}
+\includegraphics[width=0.96\linewidth, keepaspectratio]{der-falke-tune}
\catcode`\[=13%force [ to start chords again
\Large
A => filktex.el +244 -0
@@ 0,0 1,244 @@
+;;; filktex -- support for editing filktex files
+
+;;; Commentary:
+
+;; TODO: adapt chords-above-text conversion from https://github.com/ssavitzky/Honu/blob/master/emacs/flktex-mode.el#L124
+
+;;; Code:
+
+; How to write a good font=lock-mode http://ergoemacs.org/emacs/elisp_syntax_coloring.html (TODO…)
+
+(defun replace-regexp-buffer (reg to)
+ (replace-regexp reg to nil (point-min) (point-max)))
+
+(defun songbook->filktex ()
+ "Convert a buffer from songbook to filktex."
+ (interactive)
+ (save-excursion
+ (replace-string "{soc}" "\\begin{refrain}" nil (point-min) (point-max))
+ (replace-string "{eoc}" "\\end{refrain}" nil (point-min) (point-max))
+ (replace-regexp-buffer "{c:Lyrics:\\(.*\\)}" "\\\\lyrics{\\1}")
+ (replace-regexp-buffer "{c:Music:\\(.*\\)}" "\\\\music{\\1}")
+ (replace-regexp-buffer "{c:\\(.*\\):}" "\\\\inset{\\1}")
+ (replace-regexp-buffer "{c:\\(.*\\)}" "\\\\inset{\\1}")
+ (replace-regexp-buffer "{\\(title\\):\\(.*\\)}" "\\\\begin{song}{\\2}")
+ (replace-regexp-buffer "{\\(t\\):\\(.*\\)}" "\\\\begin{song}{\\2}")
+ (replace-regexp-buffer "{\\(subtitle\\):\\(.*\\)}" "\\\\subtitle{\\2}")
+ (replace-regexp-buffer "{\\(st\\):\\(.*\\)}" "\\\\subtitle{\\2}")
+ (replace-regexp-buffer "{\\(tag\\):\\(.*\\)}" "\\\\tags{\\2}")
+ (replace-regexp-buffer "{\\(time\\):\\(.*\\)}" "\\\\timing{\\2}")
+ ;; add verse breaks
+ (replace-regexp-buffer "\n *\n" "\n\\\\\\\\\n")
+ ;; comment out unknown commands on their own lines
+ (replace-regexp-buffer "^ *{\\(.*\\)} *$" "% \\1")
+ ;; fix literal &
+ (replace-string "&" "\\&" nil (point-min) (point-max))
+ ;; add potentially missing begin song
+ (goto-char (point-min))
+ (when (not (search-forward "\\begin{song}"))
+ (insert "\\begin{song}{TITLE}"))
+ (goto-char (point-max))
+ (insert "\n\\end{song}")))
+
+(defun filktex-mode-previous-definition ()
+ "Go to the previous verse, or to the start of the file."
+ (interactive)
+ (beginning-of-line)
+ (if (search-backward-regexp (rx (sequence (or "\n" "\\" "}") (* whitespace) "\n" (* whitespace) (or word-start "["))) nil t)
+ (when (match-end 0) (goto-char (match-end 0)))
+ ;; if the search fails, go to the beginning of the file
+ (goto-char (point-min)))
+ (when (equal (char-before (point)) (string-to-char "["))
+ (forward-char -1)))
+
+(defun filktex-mode-next-definition ()
+ "Go to the next verse, or to the end of the file."
+ (interactive)
+ (when (not
+ (search-forward-regexp (rx (sequence (or "\n" "\\" "}") (* whitespace) "\n" (* whitespace) (or word-start "["))) nil t))
+ ;; if the search fails, go to the end of the file
+ (goto-char (point-max)))
+ (when (equal (char-before (point)) (string-to-char "["))
+ (forward-char -1)))
+
+
+(defun filktex-mode-control-activate ()
+ (local-set-key "\M-n" 'filktex-mode-next-definition)
+ (local-set-key "\M-p" 'filktex-mode-previous-definition))
+
+;; TODO: use tex-mode for keywords (require 'tex-mode)
+
+(define-generic-mode 'filktex-mode ;; note: see customize group font lock faces to select faces
+ '(("%" . nil)) ; comments
+ '("song" "subtitle" "tags" "timing" "tailnotice" "tailnote" "begin" "end" "pagebreak" "twocolumn") ; keywords
+ '(("{\\|}" 0 'font-lock-builtin-face t) ;; any curly brace: { or }
+ ("\\[\\([^\]]+\\)\\]" 1 'font-lock-constant-face t) ;; chords, i.e. [Dm]
+ ("\\\\\\([^{ ]*\\){\\([^}]+\\)}" 1 'font-lock-function-face) ;; i.e. \subtitle{some song}
+ ("\\\\\\([^{ ]*\\){\\([^}]+\\)}" 2 'font-lock-string-face) ;; i.e. \subtitle{some song}
+ )
+ '(".*\\.flk") ; auto-mode-alist
+ '(filktex-mode-control-activate)
+ "Generic mode for filktex files.")
+
+
+;;; Convert lyrics from "chords above text" to chords inline in brackets.
+;;; by Steve Savitzky: https://github.com/ssavitzky/Honu/blob/master/emacs/flktex-mode.el#L124
+(defun flk-inline-chords-at-point ()
+ "Convert the two lines at point from chords-over-lyrics to chords-inline.
+If executed on an empty line, it inserts two backslashes to mark the end of a verse."
+ (interactive)
+ (beginning-of-line)
+ (if (looking-at "^[:space:]*$")
+ (progn (flk-gobble-line) (insert "\\\\"))
+ ;; this would be simpler in Haskell, where a string is just a list of characters.
+ ;; as it is, we use lists to avoid creating unnecessary intermediate strings.
+ (mapc 'insert (flk-inline-chords (flk-gobble-line) (flk-gobble-line))))
+ (insert "\n"))
+
+(defun flk-gobble-line ()
+ "Remove the line at point, and return it as a list of 1-character strings."
+ (let ((c (char-after)))
+ (if (or (null c) (char-equal ?\n c))
+ (progn (delete-char 1) nil)
+ (cons (string c) (progn (delete-char 1) (flk-gobble-line)))
+ )))
+
+(defun flk-inline-chords (chords lyrics)
+ "This function takes a line of chords and a line of lyrics, passed as lists of
+single-character strings, and converts them to a single line with chords inlined
+in brackets, returned as a list of strings.
+ If the lyrics (second) line is empty, return both lines unchanged."
+ (if (null lyrics)
+ (reverse (cons "\n" (reverse chords)))
+ (reverse (flk-convert-chords chords lyrics nil))))
+
+(defun flk-convert-chords (chords lyrics result)
+ "This function converts a line of chords and a line of lyrics into a list of strings
+in reverse order. We do it this way to take advantage of tail recursion."
+ (cond ((and (null chords) (null lyrics))
+ result) ; we're done
+ ((null chords)
+ ;; nothing left in chords; this just pushes the remaining lyrics onto result
+ (flk-convert-chords nil (cdr lyrics) (cons (car lyrics) result)))
+ ((equal " " (car chords))
+ (if (null lyrics)
+ (flk-convert-chords (cdr chords) nil (cons " " result))
+ (flk-convert-chords (cdr chords) (cdr lyrics) (cons (car lyrics) result))))
+ ((flk-convert-chord chords lyrics "" (cons "[" result)))
+ ))
+
+(defun flk-convert-chord (chords lyrics lyrics-under-chord result)
+ "Convert a chord at the front of lyrics, and follow it with the remaining lyrics.
+The lyrics under the chord are accumulated in a string."
+ (cond ((or (null chords) (equal " " (car chords)))
+ ;; we're done with this chord.
+ (flk-convert-chords chords lyrics (cons (concat "]" lyrics-under-chord) result)))
+ ((null lyrics)
+ (flk-convert-chord (cdr chords) nil
+ lyrics-under-chord
+ (cons (flk-convert-chord-char (car chords) (cdr chords)) result)))
+ ((flk-convert-chord (cdr chords) (cdr lyrics)
+ (concat lyrics-under-chord (car lyrics))
+ (cons (flk-convert-chord-char (car chords) (cdr chords)) result)))
+ ))
+
+;;; Convert a single character in a chord.
+;;; # -> \sharp
+;;; b -> \flat
+;;; m -> \min -- just \m if followed by a or i
+;;; \s -> \s if followed by u, else s
+;;;
+(defun flk-convert-chord-char (char rest)
+ (cond ((equal "#" char) "\\sharp")
+ ((equal "b" char) "\\flat")
+ ((equal "m" char) (cond ((null rest) "\\min")
+ ((or (equal "i" (car rest))
+ (equal "a" (car rest)))
+ "\\m")
+ ("\\min")))
+ ((equal "s" char) (cond ((and (listp rest)
+ (equal "u" (car rest)))
+ "\\s")
+ ("s")))
+ (char)))
+
+; for debugging -- really ought to make a test suite
+;(setq ch '("a" " " "b" " " "c"))
+;(setq ly '("x" "y" " " "z"))
+;(flk-inline-chords ch ly)
+
+
+(defun filktex--new-song ()
+ "Choose a new file in folder CATEGORY."
+ (interactive)
+ (let* ((default-directory (expand-file-name "~/Schreibtisch/Liederbuch/"))
+ (read-file-name-function 'read-file-name-default)
+ (filename ".flk"))
+ (filktex--create-song-file
+ (read-file-name "Open new song file: " default-directory nil nil filename))))
+
+
+(defcustom filktex--song-template
+"\\begin{song}[long]{BASENAME} % long for double-page songs
+% to add a tune, see child-of-the-library.flk
+\\index{BASENAME} % shown in the first-line index
+% \\subtitle{}
+% \\begin{twocolumns}
+
+\\begin{refrain}
+
+\\end{refrain}
+
+Songtext
+\\\\
+Songtext
+
+\\begin{refrain}
+ \\inset{REFRAIN}
+\\end{refrain}
+\\begin{bridge}
+ \\inset{BRIDGE}
+\\end{bridge}
+\\begin{note}
+\\end{note}
+\\begin{quotation}
+\\end{quotation}
+% \\columnbreak % break column for twocolumn-mode
+% \\pagebreak % break page for twocolumn-mode
+\\\\
+% \\end{twocolumns}
+% \\tags{funny}
+% \\category{english}
+% \\key{em}
+% \\timing{6:00}
+% \\music{} % copyright
+% \\lyrics{} % copyright
+% \\arranger{} % copyright
+% \\description{}
+% \\dedication{}
+% \\notice{} % copyright notice and other notes
+% \\tailnote{} % note at the end
+\\end{song}
+" "Song template for new songs."
+:type 'string :group 'filktex)
+
+(defun filktex--create-song-file (filename)
+ "Create the new article in the CATEGORY with the FILENAME, adding the required link in configure.ac."
+ (let* ((read-file-name-function 'read-file-name-default)
+ (nondirectory (file-name-nondirectory filename))
+ (basename (file-name-base filename)))
+ (save-mark-and-excursion
+ (save-window-excursion
+ (find-file-existing "zongbook.tex")
+ (goto-char (point-max))
+ (search-backward "\\file{")
+ (goto-char (point-at-eol))
+ (insert (concat "\n\\file{" nondirectory "}\n"))
+ (save-buffer)))
+
+ (find-file filename)
+ (insert (string-replace "BASENAME" basename filktex--song-template))
+ (goto-char (point-min))))
+
+(provide 'filktex)
+;;; filktex.el ends here
M zongbook.tex +1 -1
@@ 18,10 18,10 @@
\begin{document}
\maketitle
+\thispagestyle{empty}
\ThisULCornerWallPaper{0.38}{draketo-dragon}
\ThisURCornerWallPaper{0.38}{draketo-dragon-mirrored}
\ThisCenterWallPaper{0.5}{SDOeclipse-bgwhite-flipped}
-
\label{fig:draketo-dragon}\label{fig:sdoeclipse-bgwhite}\label{fig:lisar}\label{fig:lisar-new}\label{fig:glider-new}\label{fig:hurricane}\label{fig:runemaster}\label{fig:thursagan}\label{fig:fencer}\label{fig:alanin-older}\label{fig:mage-red-female}\label{fig:mage-arch-female}
\newpage