From 76c419f952a65384e759646d313c52a7b398e697 Mon Sep 17 00:00:00 2001 From: Dominic Radermacher Date: Fri, 6 Mar 2026 08:20:32 +0100 Subject: [PATCH] Add support for using \n for new line (thanks to github.com/probonopd/) --- po/de.po | 62 +++++++++++++++++++------------------- po/en.po | 62 +++++++++++++++++++------------------- po/ptouch.pot | 62 +++++++++++++++++++------------------- ptouch-print.1 | 6 ++-- src/ptouch-print.c | 74 ++++++++++++++++++++++++++++++++++++---------- 5 files changed, 156 insertions(+), 110 deletions(-) diff --git a/po/de.po b/po/de.po index b6f7fcc..2f0ba7a 100644 --- a/po/de.po +++ b/po/de.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ptouch-print 1.7\n" "Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n" -"POT-Creation-Date: 2026-02-27 07:49+0100\n" +"POT-Creation-Date: 2026-03-06 08:07+0100\n" "PO-Revision-Date: 2024-05-23 22:27-0400\n" "Last-Translator: dominic@familie-radermacher.ch\n" "Language-Team: German \n" @@ -155,149 +155,149 @@ msgstr "" msgid "debug: called ptouch_sendraster() with NULL ptdev\n" msgstr "" -#: src/ptouch-print.c:151 +#: src/ptouch-print.c:153 #, c-format msgid "nothing to print\n" msgstr "" -#: src/ptouch-print.c:159 +#: src/ptouch-print.c:161 #, c-format msgid "image is too large (%ipx x %ipx)\n" msgstr "Bild ist zu gross (%ipx x %ipx)\n" -#: src/ptouch-print.c:160 +#: src/ptouch-print.c:162 #, c-format msgid "maximum printing width for this tape is %ipx\n" msgstr "Maximal druckbare Breite für dieses Schriftband sind %ipx\n" -#: src/ptouch-print.c:163 +#: src/ptouch-print.c:165 #, fuzzy, c-format msgid "image size (%ipx x %ipx)\n" msgstr "Bild ist zu gross (%ipx x %ipx)\n" -#: src/ptouch-print.c:173 +#: src/ptouch-print.c:175 #, c-format msgid "ptouch_rasterstart() failed\n" msgstr "ptouch_rasterstart() fehlgeschlagen\n" -#: src/ptouch-print.c:179 +#: src/ptouch-print.c:181 #, c-format msgid "send print information command\n" msgstr "" -#: src/ptouch-print.c:185 +#: src/ptouch-print.c:187 #, c-format msgid "send PT-D460BT magic commands\n" msgstr "" -#: src/ptouch-print.c:192 +#: src/ptouch-print.c:194 #, c-format msgid "send precut command\n" msgstr "" -#: src/ptouch-print.c:201 +#: src/ptouch-print.c:203 #, c-format msgid "send PT-D460BT chain commands\n" msgstr "" -#: src/ptouch-print.c:213 +#: src/ptouch-print.c:215 #, fuzzy, c-format msgid "ptouch_sendraster() failed\n" msgstr "ptouch_send() fehlgeschlagen\n" -#: src/ptouch-print.c:262 +#: src/ptouch-print.c:264 #, c-format msgid "writing image '%s' failed\n" msgstr "Schreiben der Bilddatei '%s' fehlgeschlagen\n" -#: src/ptouch-print.c:284 +#: src/ptouch-print.c:286 #, c-format msgid "debug: o baseline offset - %d\n" msgstr "" -#: src/ptouch-print.c:285 +#: src/ptouch-print.c:287 #, c-format msgid "debug: text baseline offset - %d\n" msgstr "" -#: src/ptouch-print.c:344 +#: src/ptouch-print.c:346 #, c-format msgid "render_text(): %i lines, font = '%s', align = '%c'\n" msgstr "" -#: src/ptouch-print.c:347 +#: src/ptouch-print.c:349 #, c-format msgid "warning: font config not available\n" msgstr "Warnung: fontconfig ist nicht verfügbar\n" -#: src/ptouch-print.c:351 +#: src/ptouch-print.c:353 #, c-format msgid "setting font size=%i\n" msgstr "setze Zeichensatzgrösse=%i\n" -#: src/ptouch-print.c:355 +#: src/ptouch-print.c:357 #, c-format msgid "could not estimate needed font size\n" msgstr "Konnte die notwendige Zeichensatzgrösse nicht bestimmen\n" -#: src/ptouch-print.c:362 +#: src/ptouch-print.c:364 #, c-format msgid "choosing font size=%i\n" msgstr "Wähle Zeichensatzgrösse %i\n" -#: src/ptouch-print.c:378 src/ptouch-print.c:412 +#: src/ptouch-print.c:380 src/ptouch-print.c:414 #, c-format msgid "error in gdImageStringFT: %s\n" msgstr "Fehler in Funktion gdImageStringFT(): %s\n" -#: src/ptouch-print.c:592 +#: src/ptouch-print.c:571 #, c-format msgid "Only up to %d lines are supported" msgstr "" -#: src/ptouch-print.c:605 +#: src/ptouch-print.c:649 msgid "No arguments supported" msgstr "" -#: src/ptouch-print.c:610 +#: src/ptouch-print.c:654 msgid "Option --writepng missing" msgstr "" -#: src/ptouch-print.c:613 +#: src/ptouch-print.c:657 msgid "Options --force_tape_width and --info can't be used together" msgstr "" -#: src/ptouch-print.c:644 +#: src/ptouch-print.c:688 #, c-format msgid "ptouch_init() failed\n" msgstr "ptouch_init() fehlgeschlagen\n" -#: src/ptouch-print.c:647 +#: src/ptouch-print.c:691 #, c-format msgid "ptouch_getstatus() failed\n" msgstr "ptouch_getstatus() fehlgeschlagen\n" -#: src/ptouch-print.c:661 +#: src/ptouch-print.c:705 #, fuzzy, c-format msgid "maximum printing width for this printer is %ldpx\n" msgstr "Maximal druckbare Breite für dieses Schriftband sind %ipx\n" -#: src/ptouch-print.c:662 +#: src/ptouch-print.c:706 #, fuzzy, c-format msgid "maximum printing width for this tape is %ldpx\n" msgstr "Maximal druckbare Breite für dieses Schriftband sind %ipx\n" -#: src/ptouch-print.c:687 +#: src/ptouch-print.c:731 #, c-format msgid "failed to load image file\n" msgstr "" -#: src/ptouch-print.c:696 +#: src/ptouch-print.c:740 #, c-format msgid "could not render text\n" msgstr "Konnte Text nicht rendern\n" -#: src/ptouch-print.c:735 +#: src/ptouch-print.c:779 #, c-format msgid "ptouch_finalize(%d) failed\n" msgstr "ptouch_finalize(%d) fehlgeschlagen\n" diff --git a/po/en.po b/po/en.po index 53c7c77..9c2db1a 100644 --- a/po/en.po +++ b/po/en.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: ptouch-print 1.7\n" "Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n" -"POT-Creation-Date: 2026-02-27 07:49+0100\n" +"POT-Creation-Date: 2026-03-06 08:07+0100\n" "PO-Revision-Date: 2024-05-23 22:26-0400\n" "Last-Translator: dominic@familie-radermacher.ch\n" "Language-Team: English \n" @@ -155,149 +155,149 @@ msgstr "" msgid "debug: called ptouch_sendraster() with NULL ptdev\n" msgstr "" -#: src/ptouch-print.c:151 +#: src/ptouch-print.c:153 #, c-format msgid "nothing to print\n" msgstr "" -#: src/ptouch-print.c:159 +#: src/ptouch-print.c:161 #, c-format msgid "image is too large (%ipx x %ipx)\n" msgstr "image is too large (%ipx x %ipx)\n" -#: src/ptouch-print.c:160 +#: src/ptouch-print.c:162 #, c-format msgid "maximum printing width for this tape is %ipx\n" msgstr "maximum printing width for this tape is %ipx\n" -#: src/ptouch-print.c:163 +#: src/ptouch-print.c:165 #, fuzzy, c-format msgid "image size (%ipx x %ipx)\n" msgstr "image is too large (%ipx x %ipx)\n" -#: src/ptouch-print.c:173 +#: src/ptouch-print.c:175 #, c-format msgid "ptouch_rasterstart() failed\n" msgstr "ptouch_rasterstart() failed\n" -#: src/ptouch-print.c:179 +#: src/ptouch-print.c:181 #, c-format msgid "send print information command\n" msgstr "" -#: src/ptouch-print.c:185 +#: src/ptouch-print.c:187 #, c-format msgid "send PT-D460BT magic commands\n" msgstr "" -#: src/ptouch-print.c:192 +#: src/ptouch-print.c:194 #, c-format msgid "send precut command\n" msgstr "" -#: src/ptouch-print.c:201 +#: src/ptouch-print.c:203 #, c-format msgid "send PT-D460BT chain commands\n" msgstr "" -#: src/ptouch-print.c:213 +#: src/ptouch-print.c:215 #, c-format msgid "ptouch_sendraster() failed\n" msgstr "ptouch_sendraster() failed\n" -#: src/ptouch-print.c:262 +#: src/ptouch-print.c:264 #, c-format msgid "writing image '%s' failed\n" msgstr "writing image '%s' failed\n" -#: src/ptouch-print.c:284 +#: src/ptouch-print.c:286 #, c-format msgid "debug: o baseline offset - %d\n" msgstr "" -#: src/ptouch-print.c:285 +#: src/ptouch-print.c:287 #, c-format msgid "debug: text baseline offset - %d\n" msgstr "" -#: src/ptouch-print.c:344 +#: src/ptouch-print.c:346 #, c-format msgid "render_text(): %i lines, font = '%s', align = '%c'\n" msgstr "" -#: src/ptouch-print.c:347 +#: src/ptouch-print.c:349 #, c-format msgid "warning: font config not available\n" msgstr "warning: font config not available\n" -#: src/ptouch-print.c:351 +#: src/ptouch-print.c:353 #, c-format msgid "setting font size=%i\n" msgstr "setting font size=%i\n" -#: src/ptouch-print.c:355 +#: src/ptouch-print.c:357 #, c-format msgid "could not estimate needed font size\n" msgstr "could not estimate needed font size\n" -#: src/ptouch-print.c:362 +#: src/ptouch-print.c:364 #, c-format msgid "choosing font size=%i\n" msgstr "choosing font size=%i\n" -#: src/ptouch-print.c:378 src/ptouch-print.c:412 +#: src/ptouch-print.c:380 src/ptouch-print.c:414 #, c-format msgid "error in gdImageStringFT: %s\n" msgstr "error in gdImageStringFT: %s\n" -#: src/ptouch-print.c:592 +#: src/ptouch-print.c:571 #, c-format msgid "Only up to %d lines are supported" msgstr "" -#: src/ptouch-print.c:605 +#: src/ptouch-print.c:649 msgid "No arguments supported" msgstr "" -#: src/ptouch-print.c:610 +#: src/ptouch-print.c:654 msgid "Option --writepng missing" msgstr "" -#: src/ptouch-print.c:613 +#: src/ptouch-print.c:657 msgid "Options --force_tape_width and --info can't be used together" msgstr "" -#: src/ptouch-print.c:644 +#: src/ptouch-print.c:688 #, c-format msgid "ptouch_init() failed\n" msgstr "ptouch_init() failed\n" -#: src/ptouch-print.c:647 +#: src/ptouch-print.c:691 #, c-format msgid "ptouch_getstatus() failed\n" msgstr "ptouch_getstatus() failed\n" -#: src/ptouch-print.c:661 +#: src/ptouch-print.c:705 #, fuzzy, c-format msgid "maximum printing width for this printer is %ldpx\n" msgstr "maximum printing width for this tape is %ipx\n" -#: src/ptouch-print.c:662 +#: src/ptouch-print.c:706 #, fuzzy, c-format msgid "maximum printing width for this tape is %ldpx\n" msgstr "maximum printing width for this tape is %ipx\n" -#: src/ptouch-print.c:687 +#: src/ptouch-print.c:731 #, c-format msgid "failed to load image file\n" msgstr "" -#: src/ptouch-print.c:696 +#: src/ptouch-print.c:740 #, c-format msgid "could not render text\n" msgstr "could not render text\n" -#: src/ptouch-print.c:735 +#: src/ptouch-print.c:779 #, c-format msgid "ptouch_finalize(%d) failed\n" msgstr "ptouch_finalize(%d) failed\n" diff --git a/po/ptouch.pot b/po/ptouch.pot index 13fbc94..d1ed231 100644 --- a/po/ptouch.pot +++ b/po/ptouch.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ptouch-print\n" "Report-Msgid-Bugs-To: dominic@familie-radermacher.ch\n" -"POT-Creation-Date: 2026-02-27 07:49+0100\n" +"POT-Creation-Date: 2026-03-06 08:13+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -153,149 +153,149 @@ msgstr "" msgid "debug: called ptouch_sendraster() with NULL ptdev\n" msgstr "" -#: src/ptouch-print.c:151 +#: src/ptouch-print.c:153 #, c-format msgid "nothing to print\n" msgstr "" -#: src/ptouch-print.c:159 +#: src/ptouch-print.c:161 #, c-format msgid "image is too large (%ipx x %ipx)\n" msgstr "" -#: src/ptouch-print.c:160 +#: src/ptouch-print.c:162 #, c-format msgid "maximum printing width for this tape is %ipx\n" msgstr "" -#: src/ptouch-print.c:163 +#: src/ptouch-print.c:165 #, c-format msgid "image size (%ipx x %ipx)\n" msgstr "" -#: src/ptouch-print.c:173 +#: src/ptouch-print.c:175 #, c-format msgid "ptouch_rasterstart() failed\n" msgstr "" -#: src/ptouch-print.c:179 +#: src/ptouch-print.c:181 #, c-format msgid "send print information command\n" msgstr "" -#: src/ptouch-print.c:185 +#: src/ptouch-print.c:187 #, c-format msgid "send PT-D460BT magic commands\n" msgstr "" -#: src/ptouch-print.c:192 +#: src/ptouch-print.c:194 #, c-format msgid "send precut command\n" msgstr "" -#: src/ptouch-print.c:201 +#: src/ptouch-print.c:203 #, c-format msgid "send PT-D460BT chain commands\n" msgstr "" -#: src/ptouch-print.c:213 +#: src/ptouch-print.c:215 #, c-format msgid "ptouch_sendraster() failed\n" msgstr "" -#: src/ptouch-print.c:262 +#: src/ptouch-print.c:264 #, c-format msgid "writing image '%s' failed\n" msgstr "" -#: src/ptouch-print.c:284 +#: src/ptouch-print.c:286 #, c-format msgid "debug: o baseline offset - %d\n" msgstr "" -#: src/ptouch-print.c:285 +#: src/ptouch-print.c:287 #, c-format msgid "debug: text baseline offset - %d\n" msgstr "" -#: src/ptouch-print.c:344 +#: src/ptouch-print.c:346 #, c-format msgid "render_text(): %i lines, font = '%s', align = '%c'\n" msgstr "" -#: src/ptouch-print.c:347 +#: src/ptouch-print.c:349 #, c-format msgid "warning: font config not available\n" msgstr "" -#: src/ptouch-print.c:351 +#: src/ptouch-print.c:353 #, c-format msgid "setting font size=%i\n" msgstr "" -#: src/ptouch-print.c:355 +#: src/ptouch-print.c:357 #, c-format msgid "could not estimate needed font size\n" msgstr "" -#: src/ptouch-print.c:362 +#: src/ptouch-print.c:364 #, c-format msgid "choosing font size=%i\n" msgstr "" -#: src/ptouch-print.c:378 src/ptouch-print.c:412 +#: src/ptouch-print.c:380 src/ptouch-print.c:414 #, c-format msgid "error in gdImageStringFT: %s\n" msgstr "" -#: src/ptouch-print.c:592 +#: src/ptouch-print.c:571 #, c-format msgid "Only up to %d lines are supported" msgstr "" -#: src/ptouch-print.c:605 +#: src/ptouch-print.c:649 msgid "No arguments supported" msgstr "" -#: src/ptouch-print.c:610 +#: src/ptouch-print.c:654 msgid "Option --writepng missing" msgstr "" -#: src/ptouch-print.c:613 +#: src/ptouch-print.c:657 msgid "Options --force_tape_width and --info can't be used together" msgstr "" -#: src/ptouch-print.c:644 +#: src/ptouch-print.c:688 #, c-format msgid "ptouch_init() failed\n" msgstr "" -#: src/ptouch-print.c:647 +#: src/ptouch-print.c:691 #, c-format msgid "ptouch_getstatus() failed\n" msgstr "" -#: src/ptouch-print.c:661 +#: src/ptouch-print.c:705 #, c-format msgid "maximum printing width for this printer is %ldpx\n" msgstr "" -#: src/ptouch-print.c:662 +#: src/ptouch-print.c:706 #, c-format msgid "maximum printing width for this tape is %ldpx\n" msgstr "" -#: src/ptouch-print.c:687 +#: src/ptouch-print.c:731 #, c-format msgid "failed to load image file\n" msgstr "" -#: src/ptouch-print.c:696 +#: src/ptouch-print.c:740 #, c-format msgid "could not render text\n" msgstr "" -#: src/ptouch-print.c:735 +#: src/ptouch-print.c:779 #, c-format msgid "ptouch_finalize(%d) failed\n" msgstr "" diff --git a/ptouch-print.1 b/ptouch-print.1 index 6af269c..99aa29d 100644 --- a/ptouch-print.1 +++ b/ptouch-print.1 @@ -56,7 +56,9 @@ file (which can be printed later using the --image printing command option). .BR \-\-text\ \fItext Print the given text at the current position. Text including spaces must be enclosed in question marks. -To print a text in multiple lines, give multiple text arguments. +Literal '\\n' or actual newline characters in the text will be treated as +line breaks. +To print a text in multiple lines, either use '\\n' or use the -n argument. Also see the .BR EXAMPLES section. @@ -107,7 +109,7 @@ Printer device could not been opened. \fBptouch-print\fR \fI--text\fR 'Hello World' Print the text 'Hello World' in one line .TP -\fBptouch-print\fR \fI--text\fR 'Hello' 'World' +\fBptouch-print\fR \fI--text\fR 'Hello' -n 'World' Print the text 'Hello World' in two lines ('Hello' in the first line and 'World' in the second line). .TP diff --git a/src/ptouch-print.c b/src/ptouch-print.c index a66ecde..7fdf477 100644 --- a/src/ptouch-print.c +++ b/src/ptouch-print.c @@ -1,7 +1,7 @@ /* ptouch-print - Print labels with images or text on a Brother P-Touch - Copyright (C) 2015-2025 Dominic Radermacher + Copyright (C) 2015-2026 Dominic Radermacher This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as @@ -18,6 +18,7 @@ */ #include +#include #include /* printf() */ #include /* exit(), malloc() */ #include @@ -75,6 +76,7 @@ gdImage *img_cutmark(int print_width); gdImage *render_text(char *font, char *line[], int lines, int print_width); void unsupported_printer(ptouch_dev ptdev); void add_job(job_type_t type, int n, char *line); +void add_text(struct argp_state *state, char *arg, bool new_job); static error_t parse_opt(int key, char *arg, struct argp_state *state); const char *argp_program_version = P_NAME " " VERSION; @@ -94,12 +96,12 @@ static struct argp_option options[] = { { 0, 0, 0, 0, "print commands:", 2}, { "image", 'i', "", 0, "Print the given image which must be a 2 color (black/white) png", 2}, - { "text", 't', "", 0, "Print line of . If the text contains spaces, use quotation marks taround it", 2}, + { "text", 't', "", 0, "Print line of . If the text contains spaces, use quotation marks around it. \\n will be replaced by a newline", 2}, { "cutmark", 'c', 0, 0, "Print a mark where the tape should be cut", 2}, { "pad", 'p', "", 0, "Add n pixels padding (blank tape)", 2}, { "chain", 10, 0, 0, "Skip final feed of label and any automatic cut", 2}, { "precut", 11, 0, 0, "Add a cut before the label (useful in chain mode for cuts with minimal waste)", 2}, - { "newline", 'n', "", 0, "Add text in a new line (up to 4 lines)", 2}, + { "newline", 'n', "", 0, "Add text in a new line (up to 4 lines). \\n will be replaced by a newline", 2}, { "align", 'a', "", 0, "Align text (when printing multiple lines)", 2}, { 0, 0, 0, 0, "other commands:", 3}, @@ -525,6 +527,58 @@ void add_job(job_type_t type, int n, char *line) last_added_job = new_job; } +void add_text(struct argp_state *state, char *arg, bool new_job) +{ + char *p = arg; + bool first_part = true; + do { + char *next1 = strstr(p, "\\n"); + char *next2 = strchr(p, '\n'); + char *next = NULL; + char *p_next = NULL; + int skip = 0; + + if (next1 && next2) { + if (next1 < next2) { + next = next1; + skip = 2; + } else { + next = next2; + skip = 1; + } + } else if (next1) { + next = next1; + skip = 2; + } else if (next2) { + next = next2; + skip = 1; + } + + if (next) { + *next = '\0'; + p_next = next + skip; + } else { + p_next = NULL; + } + + if (new_job && first_part) { + add_job(JOB_TEXT, 1, p); + } else { + if (!last_added_job || last_added_job->type != JOB_TEXT) { + add_job(JOB_TEXT, 1, p); + } else { + if (last_added_job->n >= MAX_LINES) { + argp_failure(state, 1, EINVAL, _("Only up to %d lines are supported"), MAX_LINES); + return; + } + last_added_job->lines[last_added_job->n++] = p; + } + } + p = p_next; + first_part = false; + } while (p); +} + static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct arguments *arguments = (struct arguments *)state->input; @@ -556,7 +610,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) break; case 't': // text //printf("adding text job with alignment %i\n", arguments->align); - add_job(JOB_TEXT, 1, arg); + add_text(state, arg, true); break; case 'c': // cutmark add_job(JOB_CUTMARK, 0, NULL); @@ -583,17 +637,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) } break; case 'n': // newline - if (!last_added_job || last_added_job->type != JOB_TEXT) { - add_job(JOB_TEXT, 1, arg); - break; - } - - if (last_added_job->n >= MAX_LINES) { // max number of lines reached - argp_failure(state, 1, EINVAL, _("Only up to %d lines are supported"), MAX_LINES); - break; - } - - last_added_job->lines[last_added_job->n++] = arg; + add_text(state, arg, false); break; case 20: // info arguments->info = true;