/* These functions were originally part of source file extrwkia.c Now (15 January 2020) put in a separate file, for reuse in the conversion of html to text for the French-Interlingua dictionary by Piet Cleij. Could have been used for the German file too. */ #include "repundrl.h" #include "stdlib.h" #include "stdio.h" #include "string.h" #include "ctype.h" static int ExpandIt (char *b, char *bb, char *e, char *ee, char *s, size_t ssize); static char *StrUline = ""; static char *EndUline = ""; /* In case a vowel is underlined, indicating a deviant stress pattern, put the word in parentheses and repeat it before those, so the word will also be found with a simple search argument without the underlining. */ int RepeatWordsWithUnderlining (char *s, size_t ssize) { char *p, *b, *bb, *e, *ee, *q; size_t len; for (p = s; *p; ) { int handled; b = strstr(p, StrUline); if (b && (e = strstr(b + strlen(StrUline), EndUline))) { /* Found an underlined string. */ #if 0 /* Now check if there are only vowels in between the tags. However, it's better not to check, because of the combi ij (which server as a diphthong in Dutch) and some errors in the dictionary (consonant before or after vowel underlined. */ q = b + strlen(StrUline); if (len = strspn(q, "aeiouyAEIOUY"), len != 1 && len != 2) { p = e + strlen(EndUline); continue; } #endif bb = b; while (bb > p && (isalnum(bb[-1]) || bb[-1] == '-')) { bb--; } if (!isalnum(*bb) && *bb != '-' && *bb != '<') bb++; ee = e; ee += strlen(EndUline); while (isalnum(*ee) || *ee == '-') ee++; #ifdef DEBUG fprintf(stderr, "%4d: Found %*.*s\n", (int)(__LINE__), (int)(ee-bb), (int)(ee-bb), bb); #endif handled = ExpandIt(b, bb, e, ee, p, ssize - (p - s)); if (handled <= 0) break; else p += handled; } else { /* No need to search for more in this line */ break; } } return 0; } /* b points to start of underline tag e points to start of underline end tag bb points to start of word with underlined letter(s) in it ee points to just after word with underlined letter(s) in it Returns number of bytes written up until after the expansion and ). Not counting what follows after that. */ static int ExpandIt (char *b, char *bb, char *e, char *ee, char *s, size_t ssize) { size_t SpaceAvailable, ExtraSpaceNeeded; char *wrk, *with, *without; /* Same pointers, but relative to buffer 'without' instead of to s */ char *bw, *bbw, *ew, *eew; int handled; SpaceAvailable = ssize - strlen(s) - 1; ExtraSpaceNeeded = 3 /* space and 2 parentheses*/ + 2 * (ee - bb) /* the word with and without the underlining tags */ - strlen(StrUline) - strlen(EndUline); if (ExtraSpaceNeeded > SpaceAvailable) { /* Do nothing, safety first. Report situation to standard error. */ fprintf(stderr, "%s line %d: LineOut = %s\nNeeded %d bytes, have only %d\n", __FILE__, (int)__LINE__, s, (int)ExtraSpaceNeeded, (int)SpaceAvailable); return -1; } if ((wrk = malloc(ssize)) == NULL) { fprintf(stderr, "%s line %d: Cannot malloc %d bytes as working buffer.\n", __FILE__, (int)__LINE__, (int)ssize); return -2; } if ((with = malloc(ee - bb + 1)) == NULL) { fprintf(stderr, "%s line %d: Cannot malloc %d bytes as working buffer.\n", __FILE__, (int)__LINE__, (int)(ee - bb + 1)); free(wrk); return -3; } if ((without = malloc(ee - bb + 1)) == NULL) { fprintf(stderr, "%s line %d: Cannot malloc %d bytes as working buffer.\n", __FILE__, (int)__LINE__, (int)(ee - bb + 1)); free(wrk); free(with); return -4; } sprintf(with, "%.*s", (int)(ee - bb), bb); strcpy(without, with); bw = without + (b - bb); ew = without + (e - bb); bbw = without + (bb - bb); eew = without + (ee - bb); memmove(ew, ew + strlen(EndUline), eew - ew - strlen(EndUline) + 1); memmove(bw, bw + strlen(StrUline), eew - bw - strlen(StrUline) - strlen(EndUline) + 1); handled = sprintf(wrk, "%.*s%s (%s)", (int)(bb - s), s, without, with); sprintf(wrk + handled, "%.*s", (int)(s + strlen(s) - ee), ee); #ifdef DEBUG fprintf(stderr, "%4d: with = %s, without = %s\n", (int)(__LINE__), with, without); fprintf(stderr, "%4d: bbw= %s, eew= %s\n", (int)(__LINE__), bb, ee); fprintf(stderr, "%4d: bw = %s, ew = %s\n", (int)(__LINE__), b , e ); fprintf(stderr, "%4d: s = %s\n", (int)(__LINE__), s); fprintf(stderr, "%4d: wrk = %s\n", (int)(__LINE__), wrk); fprintf(stderr, "%4d: handled bytes = %d\n\n", (int)(__LINE__), handled); #endif strcpy(s, wrk); free(wrk); free(with); free(without); return handled; }