Blob Blame Raw


#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <helianthus.h>


typedef struct {
  int mode;
  char c[4];
} UChar;

char *ca[] = { "а", "е", "ё", "и", "о", "у", "ы", "э", "ю", "я",
               "А", "Е", "Ё", "И", "О", "У", "Ы", "Э", "Ю", "Я" };
char *cb[] = { "б", "в", "г", "д", "ж", "з", "й", "к", "л", "м", "н", "п", "р", "с", "т", "ф", "х", "ц", "ч", "ш", "щ",
               "Б", "В", "Г", "Д", "Ж", "З", "Й", "К", "Л", "М", "Н", "П", "Р", "С", "Т", "Ф", "Х", "Ц", "Ч", "Ш", "Щ" };
char *cc[] = { "ъ", "ь",
               "Ъ", "Ь" };


void splitWord(UChar *word, FILE *fo) {
  UChar *pos = word;
  UChar *pa = NULL;
  int count = 0;
  while(word->c[0]) {
    if (word->mode == 1) {
      if (pa) {
        int cnt = count / 2;
        while(pos <= pa) fputs((pos++)->c, fo);
        while(cnt > 0) {
          fputs((pos++)->c, fo);
          if (pos->mode != 3) --cnt;
        }
        //fprintf(fo, "[%d]", count);
        fputs("\u030D\u0329", fo);
        //fputs("|", fo);
      }
      pa = word;
      count = 0;
    } else
    if (pa && word->mode != 3) {
      ++count;
    }
    ++word;
  }
  while(pos < word) fputs((pos++)->c, fo);
}


int findStr(char *str, char **list, int count) {
  while(count-- > 0)
    if (strcmp(str, *list++) == 0) return 1;
  return FALSE;
}


void readUChar(UChar *uc, FILE *fi) {
  memset(uc, 0, sizeof(*uc));
  int c = fgetc(fi);
  int cnt = 1;
  if (c > 128 + 64 + 32 + 16) cnt = 4; else
  if (c > 128 + 64 + 32) cnt = 3; else
  if (c > 128 + 64) cnt = 2; else
  if (c <= 0) return;

  uc->c[0] = c;
  for(int i = 1; i < cnt; ++i)
    uc->c[i] = fgetc(fi);

  if (findStr(uc->c, ca, sizeof(ca)/sizeof(*ca))) uc->mode = 1; else
  if (findStr(uc->c, cb, sizeof(cb)/sizeof(*cb))) uc->mode = 2; else
  if (findStr(uc->c, cc, sizeof(cc)/sizeof(*cc))) uc->mode = 3;
  //printf("readUChar: m%d [%s], %d\n", uc->mode, uc->c, (int)uc->c[0]);
}


void splitFile(FILE *fi, FILE *fo) {
  UChar word[1024];
  UChar *pc = word, *pe = word + sizeof(word)/sizeof(*word), uc = {};
  while(1) {
    readUChar(&uc, fi);
    if (uc.mode && pc < pe) {
      memcpy(pc++, &uc, sizeof(uc));
    } else {
      if (pc > word) {
        pc->c[0] = 0;
        splitWord(word, fo);
        pc = word;
      }
      if (!uc.c[0]) break;
      fputs(uc.c, fo);
    }
  }
}


void init() {
  FILE *fi = fopen("data/text-to-split.txt", "r");
  FILE *fo = fopen("data/output/splitted-text.txt", "w");
  if (fi && fo) splitFile(fi, fo);
  if (fi) fclose(fi);
  if (fo) fclose(fo);
}


void draw() {
  text(10, 10, "loaded from: data/text-to-split.txt\n"
               "saved to: data/output/splitted-text.txt");
}


int main() {
  windowSetResizable(TRUE);
  windowSetInit(&init);
  windowSetDraw(&draw);
  windowRun();
  return 0;
}