From 7aff48a428f5c9c765f71d364594a9f273d04e8a Mon Sep 17 00:00:00 2001 From: david Date: Tue, 13 Oct 2026 23:04:06 -0300 Subject: [PATCH] split text --- .gitignore | 1 + configure | 26 ++++++++--------- configure.ac | 2 +- defs/helper.h | 1 + src/helper.c | 2 +- src/main.c | 78 ++++++++++++++++++++++++++++++++++++++++++++------- 6 files changed, 85 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 348d929..fb06c7d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ mikusays *.tar.gz .dirstamp +configure~ diff --git a/configure b/configure index 6ba4aa4..a9fc3c8 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.73 for mikusays 0.2.0. +# Generated by GNU Autoconf 2.73 for mikusays 0.3.1. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2026 Free Software Foundation, @@ -584,10 +584,10 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='mikusays' PACKAGE_TARNAME='mikusays' -PACKAGE_VERSION='0.2.0' -PACKAGE_STRING='mikusays 0.2.0' +PACKAGE_VERSION='0.3.1' +PACKAGE_STRING='mikusays 0.3.1' PACKAGE_BUGREPORT='' -PACKAGE_URL='https://github.com/davideldios7/mikusays' +PACKAGE_URL='https://git.squeakyrat.moe/mikusays-c' ac_unique_file="src/main.c" # Factoring default headers for most tests. @@ -1281,7 +1281,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures mikusays 0.2.0 to adapt to many kinds of systems. +'configure' configures mikusays 0.3.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1348,7 +1348,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of mikusays 0.2.0:";; + short | recursive ) echo "Configuration of mikusays 0.3.1:";; esac cat <<\_ACEOF @@ -1379,7 +1379,7 @@ Use these variables to override the choices made by 'configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. -mikusays home page: . +mikusays home page: . _ACEOF ac_status=$? fi @@ -1443,7 +1443,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -mikusays configure 0.2.0 +mikusays configure 0.3.1 generated by GNU Autoconf 2.73 Copyright (C) 2026 Free Software Foundation, Inc. @@ -1555,7 +1555,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by mikusays $as_me 0.2.0, which was +It was created by mikusays $as_me 0.3.1, which was generated by GNU Autoconf 2.73. Invocation command line was $ $0$ac_configure_args_raw @@ -3171,7 +3171,7 @@ fi # Define the identity of the package. PACKAGE='mikusays' - VERSION='0.2.0' + VERSION='0.3.1' printf '%s\n' "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -5437,7 +5437,7 @@ cat >>"$CONFIG_STATUS" <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mikusays $as_me 0.2.0, which was +This file was extended by mikusays $as_me 0.3.1, which was generated by GNU Autoconf 2.73. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5489,7 +5489,7 @@ Configuration commands: $config_commands Report bugs to the package provider. -mikusays home page: ." +mikusays home page: ." _ACEOF ac_cs_config=`printf '%s\n' "$ac_configure_args" | sed "$ac_safe_unquote"` @@ -5497,7 +5497,7 @@ ac_cs_config_escaped=`printf '%s\n' "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>"$CONFIG_STATUS" <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -mikusays config.status 0.2.0 +mikusays config.status 0.3.1 configured by $0, generated by GNU Autoconf 2.73, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 6e55ac6..70de584 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.69]) -AC_INIT([mikusays], [0.3.0], [], [mikusays], [https://github.com/davideldios7/mikusays]) +AC_INIT([mikusays], [0.3.1], [], [mikusays], [https://git.squeakyrat.moe/mikusays-c]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign subdir-objects -Wall]) diff --git a/defs/helper.h b/defs/helper.h index a8a7988..da63409 100644 --- a/defs/helper.h +++ b/defs/helper.h @@ -3,5 +3,6 @@ int displaywidth(const char *text); int utf8_decode(const unsigned char *bytes, unsigned long *codepoint); +int codepoint_width(unsigned long codepoint); #endif diff --git a/src/helper.c b/src/helper.c index f258d23..108e2b9 100644 --- a/src/helper.c +++ b/src/helper.c @@ -48,7 +48,7 @@ int utf8_decode(const unsigned char *bytes, unsigned long *codepoint){ } /* this turns the library's return value into a column count so 0 1 or 2 */ -static int codepoint_width(unsigned long codepoint){ +int codepoint_width(unsigned long codepoint){ int width = widechar_wcwidth(codepoint); if(width > 0) return width; diff --git a/src/main.c b/src/main.c index c6879b6..350832e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,5 @@ #include "../defs/all.h" #include "../defs/mikuart.h" -#include -#include char **getmikuart(int style){ if(style < 0) @@ -55,6 +53,43 @@ static void freelines(char **lines){ free(lines); } +static char **push_chunk(char **chunks, int *count, const char *start, size_t len){ + chunks = realloc(chunks, (*count + 2) * sizeof(char *)); + chunks[*count] = malloc(len + 1); + memcpy(chunks[*count], start, len); + chunks[*count][len] = '\0'; + (*count)++; + chunks[*count] = NULL; + return chunks; +} + +char **split_word_by_width(const char *word, int max_width){ + char **chunks = NULL; + int count = 0; + size_t length = strlen(word); + size_t start = 0, i = 0; + int chunk_width = 0; + + while(i < length){ + unsigned long codepoint; + int bytes = utf8_decode((const unsigned char *)word + i, &codepoint); + int width = codepoint_width(codepoint); + + if(i > start && chunk_width + width > max_width){ + chunks = push_chunk(chunks, &count, word + start, i - start); + start = i; + chunk_width = 0; + } + chunk_width += width; + i += bytes; + } + + if(i > start) + chunks = push_chunk(chunks, &count, word + start, i - start); + + return chunks; +} + char **wraptext(const char *text, int max, int *count){ char *copy = strdup(text); char *current_line = calloc(strlen(text)+1, sizeof(char)); @@ -69,17 +104,40 @@ char **wraptext(const char *text, int max, int *count){ } strcat(current_line, tok); } else{ - if(current_line[0] != '\0'){ - lines = realloc(lines, (*count + 2) * sizeof(char *)); - lines[*count] = strdup(current_line); - (*count)++; - lines[*count] = NULL; - } - strcpy(current_line, tok); + if(displaywidth(tok) > max){ + if(current_line[0] != '\0'){ + lines = realloc(lines, (*count + 2) * sizeof(char *)); + lines[*count] = strdup(current_line); + (*count)++; + lines[*count] = NULL; + } + + char **chunks = split_word_by_width(tok, max); + int n = 0; + while(chunks[n] != NULL) n++; + + for(int i = 0; i < n - 1; i++){ + lines = realloc(lines, (*count + 2) * sizeof(char *)); + lines[*count] = chunks[i]; + (*count)++; + lines[*count] = NULL; + } + + strcpy(current_line, chunks[n - 1]); + free(chunks[n - 1]); + free(chunks); + } else{ + if(current_line[0] != '\0'){ + lines = realloc(lines, (*count + 2) * sizeof(char *)); + lines[*count] = strdup(current_line); + (*count)++; + lines[*count] = NULL; + } + strcpy(current_line, tok); + } } tok = strtok(NULL, " \t\n"); } - if(current_line[0] != '\0'){ lines = realloc(lines, (*count + 2) * sizeof(char *)); lines[*count] = strdup(current_line);