cho2txt

Extract lyrics from chordpro files
git clone git://git.relim.de/cho2txt.git
Log | Files | Refs | README | LICENSE

commit a266ccfbacd803c0e0358b1494af5778586e1b8e
Author: nibo <kroekerrobin@gmail.com>
Date:   Tue, 27 Jun 2023 13:53:20 +0200

Initial commit

Diffstat:
AA_Closer_Walk.cho | 29+++++++++++++++++++++++++++++
AMakefile | 17+++++++++++++++++
AO_du_froehliche.cho | 23+++++++++++++++++++++++
Acho2txt | 0
Acho2txt.1 | 10++++++++++
Acho2txt.c | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 182 insertions(+), 0 deletions(-)

diff --git a/A_Closer_Walk.cho b/A_Closer_Walk.cho @@ -0,0 +1,29 @@ +{title: A Closer Walk} + +{sov: Verse 1} +[G]I am weak but Thou art [Am]strong [D] +[Am]Jesus [D]keep me from all [G]wrong [D7] +[G]I’ll be [G7]satisfied as [C]long [A7] +As I [G]walk let me [D]walk close to [G]Thee [D7] +{eov} + +{soc: Chorus} +[G]Just a closer walk with [Am]thee [D] +[Am]Grant it [D]Jesus is my [G]plea [D7] +[G]Daily [G7]walking close to [C]Thee [A7] +Let it [G]be dear [D]Lord let it [G]be [D7] +{eoc} + +{sov: Verse 2} +[G]Through this world of toil and [Am]snares [D] +[Am]If I [D]falter Lord who [G]cares [D7] +[G]Who with [G7]me my burden [C]shares [A7] +None but [G]Thee dear [D7]Lord none but [G]Thee [D7] +{eov} + +{sov: Verse 3} +[G]When my feeble life is [Am]o’er [D] +[Am]Time for [D]me will be no [G]more [D7] +[G]Guide me [G7]gently safely [C]o’er [A7] +To Thy [G]kingdom [D]shore to Thy [G]shore [D7] +{eov} diff --git a/Makefile b/Makefile @@ -0,0 +1,17 @@ +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/share/man + +all: + $(CC) -O -Werror -o cho2txt cho2txt.c +clean: + rm cho2txt +install: all + mkdir -p "$(PREFIX)/bin" + cp -f snd "$(PREFIX)/bin" + chmod 755 "$(PREFIX)/bin/cho2txt" + mkdir -p "$(MANPREFIX)/man1" + cp -f snd.1 "$(MANPREFIX)/man1/cho2txt.1" + chmod 644 "$(MANPREFIX)/man1/cho2txt.1" +uninstall: + rm "$(PREFIX)/bin/cho2txt" + rm "$(MANPREFIX)/man1/cho2txt.1" diff --git a/O_du_froehliche.cho b/O_du_froehliche.cho @@ -0,0 +1,23 @@ +{title: O du fröhliche} +{key: C} + +{sov: 1. Strophe} +[C]O [F]du [C]fröhliche, o [F]du [C]selige +Gna[G]den[D]bring[G]en[C]de [G]Weih[D]nachts[G]zeit! +Welt ging verloren, [C]Christ ist geboren +Freue, [F]freue dich, o [C]Christ[G]en[C]heit! +{eov} + +{sov: 2. Strophe} +[C]O [F]du [C]fröhliche, o [F]du [C]selige +Gna[G]den[D]bring[G]en[C]de [G]Weih[D]nachts[G]zeit! +Christ ist erschienen, [C]uns zu versöhnen +Freue, [F]freue dich, o [C]Christ[G]en[C]heit! +{eov} + +{sov: 3. Strophe} +[C]O [F]du [C]fröhliche, o [F]du [C]selige +Gna[G]den[D]bring[G]en[C]de [G]Weih[D]nachts[G]zeit! +Himmlische Heere [C]jauchzen dir Ehre! +Freue, [F]freue dich, o [C]Christ[G]en[C]heit! +{eov} diff --git a/cho2txt b/cho2txt Binary files differ. diff --git a/cho2txt.1 b/cho2txt.1 @@ -0,0 +1,10 @@ +.TH "CHO2TXT 1" "June 2023" "User Commands" +.SH NAME +cho2txt - Extract lyrics from chordpro files +.SH SYNOPSIS +.B cho2txt +[ filepath ] +.SH DESCRIPTION +.PP +Provide a chordpro file via the first argument or pipe the contents of the chordpro file via stdin. +The lyrics will be extracted and '\\n', '\\t' and ' ' will be trimmed at the beginning and the end. diff --git a/cho2txt.c b/cho2txt.c @@ -0,0 +1,103 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdbool.h> +#include <string.h> + +char *extractLyrics(int fd) +{ + char *text = malloc(sizeof(char)); + int i = 0; + char buf; + bool isLyrics = true; + while (1) + { + if (read(fd, &buf, 1) == 1) + { + if (buf == '{') + isLyrics = false; + if (buf == '[') + isLyrics = false; + if (isLyrics) + { + text[i] = buf; + i++; + text = realloc(text, (i+1) * sizeof(char)); + } + if (buf == '}') + isLyrics = true; + if (buf == ']') + isLyrics = true; + } + else + break; + } + text[i] = '\0'; + return text; +} + +char *trimText(char *text) +{ + char *trimmedText = NULL; + int begin = 0; + int end = 0; + for (int i=0; i<strlen(text); i++) + { + if (text[i] == ' ' || text[i] == '\n' || text[i] == '\t') + begin++; + else + break; + } + for (int i=strlen(text)-1; i>=0; i--) + { + if (text[i] == ' ' || text[i] == '\n' || text[i] == '\t') + end++; + else + break; + } + int k = 0; + for (int i=0; i<strlen(text); i++) + { + if (i >= begin && i < strlen(text) - end) + { + trimmedText = realloc(trimmedText, (k+1) * sizeof(char)); + trimmedText[k] = text[i]; + k++; + } + } + trimmedText = realloc(trimmedText, (k+1) * sizeof(char)); + trimmedText[k] = 0; + free(text); + return trimmedText; +} + +int main(int argc, char *argv[]) +{ + char *lyrics, *trimmedLyrics; + switch (argc) + { + case 1: + lyrics = extractLyrics(0); + trimmedLyrics = trimText(lyrics); + printf("%s\n", trimmedLyrics); + free(trimmedLyrics); + break; + case 2: + int fd = open(argv[1], O_RDONLY); + if (fd == -1) + { + fprintf(stderr, "open failed.\n"); + return -1; + } + lyrics = extractLyrics(fd); + trimmedLyrics = trimText(lyrics); + printf("%s\n", trimmedLyrics); + free(trimmedLyrics); + break; + default: + fprintf(stderr, "Either provide exactly one file or no file for reading from stdin.\n"); + return -1; + } + return 0; +}