From 3ce7811758c351df069ae36c55886af8b577cb66 Mon Sep 17 00:00:00 2001
From: dx <aryadevchavali1@gmail.com>
Date: Wed, 6 May 2020 06:03:32 +0100
Subject: +routine to compile plain text +diagnostics

This routine will handle asterisks and bullet points.
Works by checking characters at each step.
Also has diagnostics by checking for matching characters. If a matching
asterisk, for example, isn't found then present an error and quit.
---
 Converter/includes/compiler.h |   3 +-
 Converter/src/compiler.c      | 112 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 109 insertions(+), 6 deletions(-)

diff --git a/Converter/includes/compiler.h b/Converter/includes/compiler.h
index b0b6d43..8b2fa1f 100644
--- a/Converter/includes/compiler.h
+++ b/Converter/includes/compiler.h
@@ -2,7 +2,8 @@
 #define __COMPILER_H_
 
 #include <stdlib.h>
+
 typedef char *string;
-string compile_line(string line, size_t size_of_line);
+string compile_line(string line, size_t size_of_line, string line_or_source);
 
 #endif // __COMPILER_H_
diff --git a/Converter/src/compiler.c b/Converter/src/compiler.c
index 1c5b728..c6060be 100644
--- a/Converter/src/compiler.c
+++ b/Converter/src/compiler.c
@@ -2,15 +2,116 @@
 #include <stdio.h>
 #include <string.h>
 
-string compile_line(string line, size_t size_of_line)
+void compile_plain_text(string dest, string src, size_t size_of_line,
+                        string line_or_source)
+{
+  /* cursor is the current index on the dest pointer
+   * lower represents the last tag character before content
+   * upper represents the first tag character after content
+   *
+   * size_of_content is self explanatory (size of content in tags)
+   * tag_size is the compiled size of a tag
+   * md_tag_size is the precompiled size of a tag
+   *
+   * tag is the string for the open HTML tag
+   * close_tag is the string for the close HTML tag
+   *
+   * i and j are iterator variables
+   */
+  int cursor, lower, upper;
+  size_t size_of_content, tag_size, md_tag_size;
+  string tag, close_tag;
+  int i, j;
+
+  lower = 0;
+  upper = 0;
+  cursor = 0;
+
+  for (i = 0; i < size_of_line; ++i)
+  {
+    // Asterisk routine
+    if (src[i] == '*')
+    {
+      j = i + 1;
+
+      // Twin asterisks
+      if (src[i + 1] == '*')
+      {
+        tag = "<strong>";
+        close_tag = "</strong>";
+        tag_size = 8;
+        md_tag_size = 2;
+
+        // Make j the cursor seeking for the matching asterisk pair
+        while ((j < size_of_line - 1) && (src[j] != '*' || src[j + 1] != '*'))
+          ++j;
+
+        // if found
+        if (src[j] == '*')
+        {
+          lower = i + 1;
+          upper = j;
+        }
+        else
+        {
+          // ERROR
+          fprintf(stderr, "No matching asterisk for %s:%d\n", line_or_source,
+                  i);
+          exit(-1);
+        }
+      }
+
+      // one asterisk
+      else
+      {
+        tag = "<i>";
+        close_tag = "</i>";
+        tag_size = 3;
+        md_tag_size = 1;
+        while ((j < size_of_line) && (src[j] != '*')) ++j;
+
+        if (src[j] == '*')
+        {
+          lower = i;
+          upper = j;
+        }
+        else
+        {
+          // error, no matching asterisk
+          fprintf(stderr, "No matching asterisk for %s:%d\n", line_or_source,
+                  i);
+          exit(-1);
+        }
+      }
+
+      /*
+       * Copy all
+       */
+      size_of_content = upper - lower - 1;
+      strncpy(dest + cursor, tag, tag_size);
+      strncpy(dest + cursor + tag_size, src + lower + 1, size_of_content);
+      strncpy(dest + cursor + tag_size + size_of_content, close_tag,
+              tag_size + 1);
+      cursor +=
+          tag_size + size_of_content + tag_size + 1; // shift after operation
+      i += size_of_content + (2 * md_tag_size) - 1;
+    }
+    else
+    {
+      strncpy(dest + cursor, &src[i], 1);
+      cursor += 1;
+    }
+  }
+}
+
+string compile_line(string line, size_t size_of_line, string line_or_source)
 {
   string compiled_line;
   size_t size_of_content;
 
+  // Compile a header
   if (line[0] == '#')
   {
-    // Compile a header
-
     // Get the level of header (h1, h2, etc)
     int depth;
     for (depth = 1; line[depth] == '#'; ++depth) continue;
@@ -38,8 +139,9 @@ string compile_line(string line, size_t size_of_line)
 
   else
   {
-    compiled_line = malloc(sizeof(*compiled_line) * size_of_line);
-    strncpy(compiled_line, line, size_of_line);
+    // Assume standard text
+    compiled_line = malloc(sizeof(*compiled_line) * size_of_line * 2);
+    compile_plain_text(compiled_line, line, size_of_line, line_or_source);
   }
 
   return compiled_line;
-- 
cgit v1.2.3-13-gbd6f