tapas

[discontinued] A small program used for compiling refer output into the APA reference format.
git clone https://noxz.tech/git/tapas.git
Log | Files | README | LICENSE

commit: a9f9f6677df5442d6356c99408c6bcf32ad2f19c
parent: d6fd69e9d81d1de509370f3e54d07f55b5fac86b
author: Chris Noxz <chris@noxz.tech>
date:   Tue, 3 Dec 2019 10:20:42 +0100
Find and replace all in strings and fix hyphenation for urls
Mtapas.c61+++++++++++++++-----
1 file changed, 47 insertions(+), 14 deletions(-)
diff --git a/tapas.c b/tapas.c
@@ -98,7 +98,8 @@ static int readstr(const char*, const char*, char*, int);
 static int readattr(const char*, const char*, char*, char*, int);
 static void setattr(char, char*);
 static void printref(int);
-static void findreplace(char*, const char*, const char*);
+static int matchcount(char*, const char*);
+static void findreplace(char*, const char*, const char*, int);
 static void wordsym();
 static void format_other();
 static void format_article();
@@ -214,22 +215,47 @@ printref(int type)
     state.ref = NULL;
 }
 
+int
+matchcount(char *source, const char *find)
+{
+    int i, j, m, c;
+    int slen = strlen(source),
+        flen = strlen(find);
+
+    for (i = 0, c = 0; i <= slen - flen; i++) {
+        for (j = 0, m = 1; j < flen; j++) {
+            if (source[i + j] != find[j] && (m = 0) == 0)
+                break;
+        }
+        if (m == 1)
+            c++;
+    }
+    return c;
+}
+
 void
-findreplace(char *source, const char *find, const char *replace)
+findreplace(char *source, const char *find, const char *replace, int start)
 {
-    char *dest = malloc(strlen(source) - strlen(find) + strlen(replace) + 1);
+    char *dest;
     char *ptr;
+    int count = matchcount(source + start, find);
+    int size = (strlen(source) + (strlen(replace) - strlen(find)) * count + 1);
+    int i;
 
+    dest = malloc(size);
     strcpy(dest, source);
-
-    ptr = strstr(dest, find);
-    if (ptr) {
-        memmove(
-            ptr + strlen(replace),
-            ptr + strlen(find),
-            strlen(ptr+strlen(find)) + 1
-        );
-        strncpy(ptr, replace, strlen(replace));
+    ptr = dest + start;
+
+    for (i = 0; i < count; i++) {
+        if ((ptr = strstr(ptr, find))) {
+            memmove(
+                ptr + strlen(replace),
+                ptr + strlen(find),
+                strlen(ptr+strlen(find)) + 1
+            );
+            strncpy(ptr, replace, strlen(replace));
+        }
+        ptr++;
     }
 
     *(source + strlen(dest)) = 0;
@@ -244,20 +270,27 @@ wordsym()
     snprintf(str_and, BUF_SIZE, " %s ", settings.and);
 
     if (state.ref->author[0])
-        findreplace(state.ref->author, " and ", str_and);
+        findreplace(state.ref->author, " and ", str_and, 0);
     if (state.ref->editor[0])
-        findreplace(state.ref->editor, " and ", str_and);
+        findreplace(state.ref->editor, " and ", str_and, 0);
 }
 
 void /* TODO :: Check type of other, website etc. */
 format_other()
 {
+    char *proto;
+
     if (!state.ref->author
         || !state.ref->publication_date
         || !state.ref->additions    /* access date */
         || !state.ref->site_name
         || !state.ref->url)
         return;
+
+    proto = strstr(state.ref->url, "://");
+    findreplace(state.ref->url, "/", "/\\:\\%",
+        proto ? (proto - state.ref->url) + 3: 0);
+
     switch (settings.macroset) {
     case ms_ms:
     fprintf(stdout,