lorid

convert chordpro to pdf
git clone git://git.relim.de/lorid.git
Log | Files | Refs | README | LICENSE

commit f93d5da85c69214eac0c7b9b7a8ecf5771654af7
parent e321cff419173fb31c3dece2b5900079b170d7da
Author: nibo <nibo@relim.de>
Date:   Tue, 30 Jul 2024 21:59:44 +0200

Implement more style options when generating pdf

Diffstat:
MMakefile | 4++--
Mchordpro.c | 2+-
Mlorid.c | 2+-
Mout_pdf.c | 123+++++++++++--------------------------------------------------------------------
Mout_pdf.h | 7-------
Dstr.c | 98-------------------------------------------------------------------------------
Dstr.h | 3---
Autil.c | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Autil.h | 17+++++++++++++++++
9 files changed, 222 insertions(+), 218 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ all: - $(CC) -pedantic -Wall -Wextra -O2 str.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml -lfontconfig + $(CC) -pedantic -Wall -Wextra -O2 util.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml -lfontconfig debug: - $(CC) -g -pedantic -Wall -Wextra str.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml -lfontconfig + $(CC) -g -pedantic -Wall -Wextra util.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml -lfontconfig fontconfig: $(CC) -g chordpro.c fontconfig.c -o fontconfig -lfontconfig .PHONY: all debug fontconfig diff --git a/chordpro.c b/chordpro.c @@ -6,7 +6,7 @@ #include <ctype.h> #include "chordpro.h" #include "config.h" -#include "str.h" +#include "util.h" static const char *environment_directives[] = { "start_of_chorus", "soc", "end_of_chorus", "eoc", "chorus", diff --git a/lorid.c b/lorid.c @@ -7,7 +7,7 @@ #include "config.h" #include "chordpro.h" #include "out_pdf.h" -#include "str.h" +#include "util.h" int main(int argc, char *argv[]) { diff --git a/out_pdf.c b/out_pdf.c @@ -1,14 +1,13 @@ #include <stdbool.h> #include <stdint.h> #include <string.h> -#include <sys/stat.h> #include <pdfio.h> #include <pdfio-content.h> #include "chordpro.h" #include "config.h" #include "out_pdf.h" #include "fontconfig.h" -#include "str.h" +#include "util.h" static struct Fnt **g_fonts = NULL; @@ -172,105 +171,6 @@ static size_t out_pdf_text_find_fitting_length(const char *str, size_t len) return len; } -static enum FileType file_type(const char *path) -{ - struct stat s; - if (stat(path, &s) != 0) { - return F_ERROR; - } - switch (s.st_mode & S_IFMT) { - case S_IFDIR: - return F_FOLDER; - case S_IFREG: - return F_REG_FILE; - } - return F_OTHER; -} - -static char *filepath_add_ending_slash_if_missing(const char *path) -{ - size_t len = strlen(path); - if (path[len-1] == '/') { - return strdup(path); - } else { - char *path_with_slash = malloc((len+2) * sizeof(char)); - strcpy(path_with_slash, path); - path_with_slash[len] = '/'; - path_with_slash[len+1] = 0; - return path_with_slash; - } -} - -static char *filepath_basename(const char *path) -{ - int begin = 0; - int i; - for (i = 0; path[i] != 0; i++) { - if (path[i] == '/') { - begin = i+1; - } - } - return strdup(&path[begin]); -} - -static char *filepath_dirname(const char *path) -{ - char *dirname; - int end = 0; - int i; - for (i = 0; path[i] != 0; i++) { - if (path[i] == '/') { - end = i; - } - } - dirname = malloc((end+1)* sizeof(char)); - i = 0; - while (i<end) { - dirname[i] = path[i]; - i++; - } - dirname[i] = 0; - return dirname; -} - -static char *file_extension_replace_or_add(const char *old) -{ - char *new = NULL; - int mark = -1; - int i = 0; - int old_len; - while (old[i] != 0) { - if (old[i] == '.') - mark = i; - i++; - } - i = 0; - if (mark == -1) { - old_len = (int)strlen(old); - new = malloc((old_len+5) * sizeof(char)); - while (i < old_len) { - new[i] = old[i]; - i++; - } - new[i] = '.'; - new[++i] = 'p'; - new[++i] = 'd'; - new[++i] = 'f'; - new[++i] = 0; - } else { - new = malloc((mark+5) * sizeof(char)); - while (i <= mark) { - new[i] = old[i]; - i++; - } - new[i] = 'p'; - new[++i] = 'd'; - new[++i] = 'f'; - new[++i] = 0; - } - return new; -} - static char *out_pdf_filename_generate_from_songs(struct ChoSong **songs) { char *filename; @@ -286,13 +186,11 @@ static char *out_pdf_filename_generate_from_songs(struct ChoSong **songs) return NULL; } normalized_title = str_normalize(title); - filename = file_extension_replace_or_add(normalized_title); + filename = file_extension_replace_or_add(normalized_title, "pdf"); free(normalized_title); return filename; } return strdup("collection-of-songs.pdf"); - /* if (len > 1) { - } */ } static char *out_pdf_filename_create(struct ChoSong **songs, const char *cho_filepath, const char *out) @@ -301,7 +199,7 @@ static char *out_pdf_filename_create(struct ChoSong **songs, const char *cho_fil char *pdf_filename; char *tmp; if (cho_filepath) { - pdf_filepath = file_extension_replace_or_add(cho_filepath); + pdf_filepath = file_extension_replace_or_add(cho_filepath, "pdf"); pdf_filename = filepath_basename(pdf_filepath); } else { pdf_filename = out_pdf_filename_generate_from_songs(songs); @@ -484,13 +382,13 @@ static bool out_pdf_draw_line(pdfio_stream_t *stream, struct TextLineItem *item, red = item->style->strikethrough_color->red / 255.0; green = item->style->strikethrough_color->green / 255.0; blue = item->style->strikethrough_color->blue / 255.0; - printf("add to y: %.2f\n", item->style->font->size * 0.21); y += item->style->font->size * 0.3; break; case LL_OVER: red = item->style->overline_color->red / 255.0; green = item->style->overline_color->green / 255.0; blue = item->style->overline_color->blue / 255.0; + y += item->style->font->size * 0.8; break; } if (!pdfioContentPathMoveTo(stream, item->x, y)) { @@ -541,6 +439,10 @@ static bool out_pdf_text_show(pdfio_stream_t *stream, struct TextLineItem *item, fprintf(stderr, "pdfioContentTextMoveTo failed.\n"); return false; } + if (!pdfioContentSetTextRise(stream, item->style->rise)) { + fprintf(stderr, "pdfioContentSetTextRise failed.\n"); + return false; + } if (!pdfioContentTextShow(stream, true, item->text)) { fprintf(stderr, "pdfioContentTextShow failed.\n"); return false; @@ -552,10 +454,19 @@ static bool out_pdf_text_show(pdfio_stream_t *stream, struct TextLineItem *item, if (item->style->underline_style == LS_SINGLE) { out_pdf_draw_line(stream, item, y, width, LL_UNDER); } else if (item->style->underline_style == LS_DOUBLE) { + out_pdf_draw_line(stream, item, y, width, LL_UNDER); + out_pdf_draw_line(stream, item, y-1.5, width, LL_UNDER); } if (item->style->strikethrough) { out_pdf_draw_line(stream, item, y, width, LL_STRIKETHROUGH); } + if (item->style->overline_style == LS_SINGLE) { + out_pdf_draw_line(stream, item, y, width, LL_OVER); + } else if (item->style->overline_style == LS_DOUBLE) { + out_pdf_draw_line(stream, item, y, width, LL_OVER); + out_pdf_draw_line(stream, item, y+1.5, width, LL_OVER); + } + // TODO: Implement style->href and style->boxed return true; } diff --git a/out_pdf.h b/out_pdf.h @@ -38,13 +38,6 @@ struct Text { struct TextLine **lines; }; -enum FileType { - F_ERROR, - F_FOLDER, - F_REG_FILE, - F_OTHER -}; - enum LineLocation { LL_OVER, LL_STRIKETHROUGH, diff --git a/str.c b/str.c @@ -1,98 +0,0 @@ -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include "str.h" - -/* char *str_normalize(const char *str) -{ - char *normalized = NULL; - int i = 0; - int s = 0; - char c; - for (; str[i] != 0; i++) { - if (str[i] == ' ') - continue; - c = (char)tolower(str[i]); - normalized = realloc(normalized, (s+1) * sizeof(char)); - normalized[s] = c; - s++; - } - normalized = realloc(normalized, (s+1) * sizeof(char)); - normalized[s] = 0; - return normalized; -} */ - -char *str_normalize(const char *str) -{ - char *normalized = NULL; - int i = 0; - int n = 0; - char c; - for (; str[i] != 0; i++) { - if (str[i] == ' ') { - normalized = realloc(normalized, (n+1) * sizeof(char)); - normalized[n] = '-'; - n++; - continue; - } - if (str[i] == '\'' || str[i] == ',') - continue; - c = (char)tolower(str[i]); - normalized = realloc(normalized, (n+1) * sizeof(char)); - normalized[n] = c; - n++; - } - normalized = realloc(normalized, (n+1) * sizeof(char)); - normalized[n] = 0; - return normalized; -} - -char *str_trim(const char *str) -{ - char *trimmed = NULL; - int begin = 0; - int end = 0; - int len = (int)strlen(str); - for (int i=0; i<len; i++) { - if ( - str[i] == ' ' || - str[i] == '\n' || - str[i] == '\t' || - str[i] == '\r' - ) - begin++; - else - break; - } - for (int i=len-1; i>=0; i--) { - if ( - str[i] == ' '|| - str[i] == '\n' || - str[i] == '\t' || - str[i] == '\r' - ) - end++; - else - break; - } - int k = 0; - for (int i=0; i<len; i++) { - if (i >= begin && i < len - end) { - trimmed = realloc(trimmed, (k+1) * sizeof(char)); - trimmed[k] = str[i]; - k++; - } - } - trimmed = realloc(trimmed, (k+1) * sizeof(char)); - trimmed[k] = 0; - return trimmed; -} - -char *str_remove_leading_whitespace(const char *str) -{ - int i = 0; - while (str[i] == ' ' || str[i] == '\t') { - i++; - } - return strdup(&str[i]); -} diff --git a/str.h b/str.h @@ -1,3 +0,0 @@ -char *str_normalize(const char *str); -char *str_trim(const char *str); -char *str_remove_leading_whitespace(const char *str); diff --git a/util.c b/util.c @@ -0,0 +1,184 @@ +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <sys/stat.h> +#include "util.h" + +char *str_normalize(const char *str) +{ + char *normalized = NULL; + int i = 0; + int n = 0; + char c; + for (; str[i] != 0; i++) { + if (str[i] == ' ') { + normalized = realloc(normalized, (n+1) * sizeof(char)); + normalized[n] = '-'; + n++; + continue; + } + if (str[i] == '\'' || str[i] == ',') + continue; + c = (char)tolower(str[i]); + normalized = realloc(normalized, (n+1) * sizeof(char)); + normalized[n] = c; + n++; + } + normalized = realloc(normalized, (n+1) * sizeof(char)); + normalized[n] = 0; + return normalized; +} + +char *str_trim(const char *str) +{ + char *trimmed = NULL; + int begin = 0; + int end = 0; + int len = (int)strlen(str); + for (int i=0; i<len; i++) { + if ( + str[i] == ' ' || + str[i] == '\n' || + str[i] == '\t' || + str[i] == '\r' + ) + begin++; + else + break; + } + for (int i=len-1; i>=0; i--) { + if ( + str[i] == ' '|| + str[i] == '\n' || + str[i] == '\t' || + str[i] == '\r' + ) + end++; + else + break; + } + int k = 0; + for (int i=0; i<len; i++) { + if (i >= begin && i < len - end) { + trimmed = realloc(trimmed, (k+1) * sizeof(char)); + trimmed[k] = str[i]; + k++; + } + } + trimmed = realloc(trimmed, (k+1) * sizeof(char)); + trimmed[k] = 0; + return trimmed; +} + +char *str_remove_leading_whitespace(const char *str) +{ + int i = 0; + while (str[i] == ' ' || str[i] == '\t') { + i++; + } + return strdup(&str[i]); +} + +enum FileType file_type(const char *path) +{ + struct stat s; + if (stat(path, &s) != 0) { + return F_ERROR; + } + switch (s.st_mode & S_IFMT) { + case S_IFDIR: + return F_FOLDER; + case S_IFREG: + return F_REG_FILE; + } + return F_OTHER; +} + +char *file_extension_replace_or_add(const char *old, const char *extension) +{ + size_t extension_len = strlen(extension); + char *new = NULL; + int mark = -1; + int i = 0; + int e = 0; + int old_len; + while (old[i] != 0) { + if (old[i] == '.') + mark = i; + i++; + } + i = 0; + if (mark == -1) { + old_len = (int)strlen(old); + new = malloc((old_len+2+extension_len) * sizeof(char)); + while (i < old_len) { + new[i] = old[i]; + i++; + } + new[i] = '.'; + while (extension[e] != 0) { + new[++i] = extension[e]; + e++; + } + new[++i] = 0; + } else { + new = malloc((mark+2+extension_len) * sizeof(char)); + while (i <= mark) { + new[i] = old[i]; + i++; + } + while (extension[e] != 0) { + new[i] = extension[e]; + i++; + e++; + } + new[i] = 0; + } + return new; +} + +char *filepath_add_ending_slash_if_missing(const char *path) +{ + size_t len = strlen(path); + if (path[len-1] == '/') { + return strdup(path); + } else { + char *path_with_slash = malloc((len+2) * sizeof(char)); + strcpy(path_with_slash, path); + path_with_slash[len] = '/'; + path_with_slash[len+1] = 0; + return path_with_slash; + } +} + +char *filepath_basename(const char *path) +{ + int begin = 0; + int i; + for (i = 0; path[i] != 0; i++) { + if (path[i] == '/') { + begin = i+1; + } + } + return strdup(&path[begin]); +} + +char *filepath_dirname(const char *path) +{ + char *dirname; + int end = 0; + int i; + for (i = 0; path[i] != 0; i++) { + if (path[i] == '/') { + end = i; + } + } + dirname = malloc((end+1)* sizeof(char)); + i = 0; + while (i<end) { + dirname[i] = path[i]; + i++; + } + dirname[i] = 0; + return dirname; +} diff --git a/util.h b/util.h @@ -0,0 +1,17 @@ +enum FileType { + F_ERROR, + F_FOLDER, + F_REG_FILE, + F_OTHER +}; + +char *str_normalize(const char *str); +char *str_trim(const char *str); +char *str_remove_leading_whitespace(const char *str); + +enum FileType file_type(const char *path); +char *file_extension_replace_or_add(const char *old, const char *extension); + +char *filepath_add_ending_slash_if_missing(const char *path); +char *filepath_basename(const char *path); +char *filepath_dirname(const char *path);