]> granicus.if.org Git - multimarkdown/commitdiff
ADDED: Add functions to insert/replace metadata
authorFletcher T. Penney <fletcher@fletcherpenney.net>
Wed, 12 Jul 2017 04:05:01 +0000 (00:05 -0400)
committerFletcher T. Penney <fletcher@fletcherpenney.net>
Wed, 12 Jul 2017 04:05:01 +0000 (00:05 -0400)
Sources/libMultiMarkdown/include/libMultiMarkdown.h
Sources/libMultiMarkdown/mmd.c
Sources/libMultiMarkdown/writer.c
Sources/libMultiMarkdown/writer.h

index 8f53910b1ce38e4e69db3b2adc579b573e1e31a2..540a89d21d0ac14bfd0adf30237421451808a78b 100644 (file)
@@ -119,6 +119,10 @@ char * mmd_string_metadata_keys(char * source);
 char * mmd_string_metavalue_for_key(char * source, const char * key);
 
 
+/// Insert/replace metadata in string, returning new string
+char * mmd_string_update_metavalue_for_key(const char * source, const char * key, const char * value);
+
+
 
 
 /*
@@ -155,6 +159,10 @@ char * mmd_d_string_metadata_keys(DString * source);
 char * mmd_d_string_metavalue_for_key(DString * source, const char * key);
 
 
+/// Insert/replace metadata value in DString
+void mmd_d_string_update_metavalue_for_key(DString * source, const char * key, const char * value);
+
+
 
 
 /*
@@ -236,6 +244,10 @@ char * mmd_engine_metadata_keys(mmd_engine * e);
 char * mmd_engine_metavalue_for_key(mmd_engine * e, const char * key);
 
 
+/// Insert/replace metadata value in mmd_engine
+void mmd_engine_update_metavalue_for_key(mmd_engine * e, const char * key, const char * value);
+
+
 
 
 /*
index 3229e0c729532b46b7a3d2ac67f9188ed0b03f64..227b2e62480080849ccb7adbee7cdbfb5145604c 100644 (file)
@@ -2143,6 +2143,111 @@ char * mmd_engine_metavalue_for_key(mmd_engine * e, const char * key) {
 }
 
 
+/// Insert/replace metadata in string, returning new string
+char * mmd_string_update_metavalue_for_key(const char * source, const char * key, const char * value) {
+       mmd_engine * e = mmd_engine_create_with_string(source, 0);
+       mmd_engine_update_metavalue_for_key(e, key, value);
+
+       DString * d = e->dstr;
+
+       mmd_engine_free(e, false);
+
+       char * result = d->str;
+       d_string_free(d, false);
+
+       return result;
+}
+
+
+/// Insert/replace metadata value in DString
+void mmd_d_string_update_metavalue_for_key(DString * source, const char * key, const char * value) {
+       mmd_engine * e = mmd_engine_create_with_dstring(source, 0);
+       mmd_engine_update_metavalue_for_key(e, key, value);
+
+       mmd_engine_free(e, false);
+}
+
+
+/// Insert/replace metadata value in mmd_engine
+void mmd_engine_update_metavalue_for_key(mmd_engine * e, const char * key, const char * value) {
+       bool has_meta = true;
+       size_t meta_end = 0;
+
+       // Check for metadata and character
+       if (!mmd_engine_has_metadata(e, &meta_end))
+               has_meta = false;
+
+       // Get clean metadata key for match
+       char * clean = label_from_string(key);
+
+       // Determine range to excise and replace
+       size_t start = -1;
+       size_t end = -1;
+       size_t len = -1;
+
+       meta * m;
+
+       for (int i = 0; i < e->metadata_stack->size; ++i)
+       {
+               m = stack_peek_index(e->metadata_stack, i);
+
+               if (strcmp(clean, m->key) == 0) {
+                       // We have a match
+                       start = m->start;
+               } else if (start != -1) {
+                       // We have already found a match
+                       if (end == -1) {
+                               // This is the next metadata key, so determine length
+                               end = m->start;
+                       }
+               }
+       }
+
+       DString * temp = d_string_new(key);
+       d_string_append(temp, ":\t");
+       d_string_append(temp, value);
+       d_string_append_c(temp, '\n');
+
+       if (start != -1) {
+               // We're replacing existing metadata
+
+               // Figure out where to start
+               char * begin = &(e->dstr->str[start]);
+
+               while (*begin != ':')
+                       begin++;
+
+               begin++;
+
+               while (char_is_whitespace(*begin))
+                       begin++;
+
+               start = begin - e->dstr->str;
+
+               if (end == -1) {
+                       // Replace until the end of the metadata (last key)
+                       len = meta_end - start;
+               } else {
+                       len = end - start;
+               }
+
+               d_string_erase(e->dstr, start, len);
+               d_string_insert(e->dstr, start, "\n");
+               d_string_insert(e->dstr, start, value);
+       } else if (meta_end != 0) {
+               // We're appending metadata at the end
+               d_string_insert(e->dstr, meta_end, temp->str);
+       } else {
+               // There is no metadata, so prepend before document
+               d_string_append_c(temp, '\n');
+               d_string_prepend(e->dstr, temp->str);
+       }
+
+       d_string_free(temp, true);
+       free(clean);
+}
+
+
 /// Convert MMD text to specified format, with specified extensions, and language
 /// Returned char * must be freed
 char * mmd_string_convert(const char * source, unsigned long extensions, short format, short language) {
index def2acd4036f382d34cc30359c3c29847008902d..914bbe03e1930b745aaa1bb6bbd80c56e59678df 100644 (file)
@@ -1082,6 +1082,7 @@ meta * meta_new(const char * source, size_t key_start, size_t len) {
                m->key = label_from_string(key);
                free(key);
                m->value = NULL;
+               m->start = key_start;
        }
 
        return m;
index 7771cf16f62f7ecbc8a8a8144b6b3d769123755f..7d6594da6ec321569d5a34794612855ad09cf07b 100644 (file)
@@ -171,6 +171,7 @@ typedef struct fn_holder fn_holder;
 struct meta {
        char *                          key;
        char *                          value;
+       size_t                          start;
        UT_hash_handle          hh;
 };