From d2569edaafac2c92a9782327370ad11e1f878495 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 26 Jan 2026 18:31:24 +0100 Subject: Add metrical MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 6 ++++-- convert-to-metrical.c | 4 ++++ libcharconv.h | 14 ++++++++++++++ libcharconv_latin.c | 13 +++++++++++++ libcharconv_metrical.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 convert-to-metrical.c create mode 100644 libcharconv_metrical.c diff --git a/Makefile b/Makefile index 615f7f2..0fa5b3a 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,8 @@ BIN =\ convert-to-rotated-45deg-ccw\ convert-to-rotated-90deg-ccw\ convert-to-invisible\ - convert-to-enclosed + convert-to-enclosed\ + convert-to-metrical LIBOBJ =\ libcharconv_decode_utf8_.o\ @@ -155,7 +156,8 @@ LIBOBJ =\ libcharconv_rotated_90deg_ccw.o\ libcharconv_invisible.o\ libcharconv_enclosed_positive.o\ - libcharconv_enclosed_negative.o + libcharconv_enclosed_negative.o\ + libcharconv_metrical.o LOBJ = $(LIBOBJ:.o=.lo) diff --git a/convert-to-metrical.c b/convert-to-metrical.c new file mode 100644 index 0000000..3f7b843 --- /dev/null +++ b/convert-to-metrical.c @@ -0,0 +1,4 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +SIMPLE(libcharconv_metrical) diff --git a/libcharconv.h b/libcharconv.h index 1c8c4b9..6693376 100644 --- a/libcharconv.h +++ b/libcharconv.h @@ -472,6 +472,20 @@ LIBCHARCONV_FUNC_(libcharconv_enclosed_positive); */ LIBCHARCONV_FUNC_(libcharconv_enclosed_negative); +/** + * Convert + * '1' to METRICAL BREVE, + * '2' to METRICAL TWO SHORTS JOINED, + * '-1' to METRICAL LONG OVER SHORT, + * '-2' to METRICAL LONG OVER TWO SHORTS, + * '_1' to METRICAL SHORT OVER LONG, + * '_2' to METRICAL TWO SHORTS OVER LONG, + * '3' to METRICAL TRISEME, + * '4' to METRICAL TETRASEME, and + * '5' to METRICAL PENTASEME + */ +LIBCHARCONV_FUNC_(libcharconv_metrical); + #undef LIBCHARCONV_FUNC_ #endif diff --git a/libcharconv_latin.c b/libcharconv_latin.c index 4b41391..2693ea4 100644 --- a/libcharconv_latin.c +++ b/libcharconv_latin.c @@ -550,6 +550,16 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz c2 = (char)(c - (UINT32_C(0x278A) - (uint_least32_t)'1')); c3 = ')'; goto conv3; + } else if (UINT32_C(0x23D6) <= c && c <= UINT32_C(0x23D9)) { + /* metrical */ + c -= (uint_least32_t)UINT32_C(0x23D6) - (uint_least32_t)'2'; + goto conv; + } else if (UINT32_C(0x23D2) <= c && c <= UINT32_C(0x23D5)) { + /* metrical */ + c -= (uint_least32_t)UINT32_C(0x23D2); + c1 = (c & 1u) ? '_' : '-'; + c2 = (c & 2u) ? '2' : '1'; + goto conv2; } else { use_switch: @@ -981,6 +991,9 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz case UINT32_C(0x2793): c1 = '('; c2 = '1'; c3 = '0'; c4 = ')'; goto conv4; case UINT32_C(0x1F10C): c1 = '('; c2 = '0'; c3 = ')'; goto conv3; + /* metrical */ + case UINT32_C(0x23D1): c1 = '1'; goto conv1; + default: no_match: *n += clen; diff --git a/libcharconv_metrical.c b/libcharconv_metrical.c new file mode 100644 index 0000000..2518a2b --- /dev/null +++ b/libcharconv_metrical.c @@ -0,0 +1,51 @@ +/* See LICENSE file for copyright and license details. */ +#include "lib-common.h" + + +enum libcharconv_result +libcharconv_metrical(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) +{ + uint_least32_t c; + *n = 0; + for (; slen--; s++) { + switch (*s) { + case '1': c = UINT32_C(0x23D1); goto conv; + case '2': c = UINT32_C(0x23D6); goto conv; + case '3': c = UINT32_C(0x23D7); goto conv; + case '4': c = UINT32_C(0x23D8); goto conv; + case '5': c = UINT32_C(0x23D9); goto conv; + case '-': + case '_': + if (!slen) + return LIBCHARCONV_INDETERMINATE; + if (s[1] != '1' && s[1] != '2') + goto no_match; + c = UINT32_C(0x23D2) + (s[0] == '_' ? 1u : 0u) + (s[1] == '2' ? 2u : 0u); + goto conv2; + default: + no_match: + *n += 1u; + break; + } + } +no_conv: + return LIBCHARCONV_NO_CONVERT; + +conv: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 1u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv2: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 2u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; +} -- cgit v1.2.3-70-g09d2