<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>parsing_functions.c</filename>
    </added>
    <added>
      <filename>utility_functions.c</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -68,8 +68,7 @@ Hacking
 It should be pretty easy to modify the program to produce other formats
 than HTML or LaTeX, and to parse syntax extensions.  A quick guide:
 
-  * `markdown_parser.leg` contains the grammar itself, the `markdown()`
-    function, and some utility functions used by the parser actions.
+  * `markdown_parser.leg` contains the grammar itself.
 
   * `markdown_output.c` contains functions for printing the `Element`
     structure in various output formats.  (This includes calling
@@ -82,9 +81,9 @@ than HTML or LaTeX, and to parse syntax extensions.  A quick guide:
     option in the main program that selects the new format. Don't forget
     to add it to the help message.
 
-  * To add syntax extensions, define them in the PEG grammar (bottom part
-    of `markdown_parser.leg`), using existing extensions as a guide.
-    New inline elements will need to be added to `Inline =`; new block
+  * To add syntax extensions, define them in the PEG grammar
+    (`markdown_parser.leg`), using existing extensions as a guide. New
+    inline elements will need to be added to `Inline =`; new block
     elements will need to be added to `Block =`. If you need to add new
     types of elements, modify the `keys` enum. By using `&amp;{ }` rules
     one can selectively disable extensions depending on command-line</diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -18,223 +18,7 @@
 #include &lt;stdbool.h&gt;
 #include &lt;assert.h&gt;
 #include &quot;markdown_peg.h&quot;
-
-extern int strcasecmp(const char *string1, const char *string2);
-int yyparse(void);
-
-/**********************************************************************
-
-  List manipulation functions
-
- ***********************************************************************/
-
-/* pushelt - push an element onto a list, returning pointer to new head */
-static element * pushelt(element *new, element *list) {
-    assert(new != NULL);
-    new-&gt;next = list;
-    return new;
-}
-
-/* reverse - reverse a list, returning pointer to new list */
-static element *reverse(element *list) {
-    element *new = NULL;
-    element *next = NULL;
-    while (list != NULL) {
-        next = list-&gt;next;
-        new = pushelt(list, new);
-        list = next;
-    }
-    return new;
-}
-
-/* concat_string_list - concatenates string contents of list of STR elements.
- * Frees STR elements as they are added to the concatenation. */
-static GString *concat_string_list(element *list) {
-    GString *result;
-    element *next;
-    result = g_string_new(&quot;&quot;);
-    while (list != NULL) {
-        assert(list-&gt;key == STR);
-        assert(list-&gt;contents.str != NULL);
-        g_string_append(result, list-&gt;contents.str);
-        next = list-&gt;next;
-        free_element(list);
-        list = next;
-    }
-    return result;
-}
-
-/**********************************************************************
-
-  Global variables used in parsing
-
- ***********************************************************************/
-
-static char *charbuf = &quot;&quot;;     /* Buffer of characters to be parsed. */
-static element *references = NULL;    /* List of link references found. */
-static element *notes = NULL;         /* List of footnotes found. */
-static element *parse_result;  /* Results of parse. */
-static int syntax_extensions;  /* Syntax extensions selected. */
-
-/**********************************************************************
-
-  Auxiliary functions for parsing actions.
-  These make it easier to build up data structures (including lists)
-  in the parsing actions.
-
- ***********************************************************************/
-
-/* mk_element - generic constructor for element */
-static element * mk_element(int key) {
-    element *result = malloc(sizeof(element));
-    result-&gt;key = key;
-    result-&gt;children = NULL;
-    result-&gt;next = NULL;
-    result-&gt;contents.str = NULL;
-    return result;
-}
-
-/* mk_str - constructor for STR element */
-static element * mk_str(char *string) {
-    element *result;
-    assert(string != NULL);
-    result = mk_element(STR);
-    result-&gt;contents.str = strdup(string);
-    return result;
-}
-
-/* mk_str_from_list - makes STR element by concatenating a
- * reversed list of strings, adding optional extra newline */
-static element * mk_str_from_list(element *list, bool extra_newline) {
-    element *result;
-    GString *c = concat_string_list(reverse(list));
-    if (extra_newline)
-        g_string_append(c, &quot;\n&quot;);
-    result = mk_element(STR);
-    result-&gt;contents.str = c-&gt;str;
-    g_string_free(c, false);
-    return result;
-}
-
-/* mk_list - makes new list with key 'key' and children the reverse of 'lst'.
- * This is designed to be used with pushelt to build lists in a parser action.
- * The reversing is necessary because pushelt adds to the head of a list. */
-static element * mk_list(int key, element *lst) {
-    element *result;
-    result = mk_element(key);
-    result-&gt;children = reverse(lst);
-    return result;
-}
-
-/* mk_link - constructor for LINK element */
-static element * mk_link(element *label, char *url, char *title) {
-    element *result;
-    result = mk_element(LINK);
-    result-&gt;contents.link = malloc(sizeof(link));
-    result-&gt;contents.link-&gt;label = label;
-    result-&gt;contents.link-&gt;url = strdup(url);
-    result-&gt;contents.link-&gt;title = strdup(title);
-    return result;
-}
-
-/* extension = returns true if extension is selected */
-static bool extension(int ext) {
-    return (syntax_extensions &amp; ext);
-}
-
-/* match_inlines - returns true if inline lists match (case-insensitive...) */
-static bool match_inlines(element *l1, element *l2) {
-    while (l1 != NULL &amp;&amp; l2 != NULL) {
-      if (l1-&gt;key != l2-&gt;key)
-            return false;
-        switch (l1-&gt;key) {
-        case SPACE:
-        case LINEBREAK:
-            break;
-        case CODE:
-        case STR:
-        case HTML:
-            if (strcasecmp(l1-&gt;contents.str, l2-&gt;contents.str) == 0)
-                break;
-            else
-                return false;
-        case EMPH:
-        case STRONG:
-        case LIST:
-            if (match_inlines(l1-&gt;children, l2-&gt;children))
-                break;
-            else
-                return false;
-        case LINK:
-        case IMAGE:
-            return false;  /* No links or images within links */
-        default:
-            fprintf(stderr, &quot;match_inlines encountered unknown key = %d\n&quot;, l1-&gt;key);
-            exit(EXIT_FAILURE);
-            break;
-        }
-        l1 = l1-&gt;next;
-        l2 = l2-&gt;next;
-    }
-    return (l1 == NULL &amp;&amp; l2 == NULL);  /* return true if both lists exhausted */
-}
-
-/* find_reference - return true if link found in references matching label.
- * 'link' is modified with the matching url and title. */
-static bool find_reference(link *result, element *label) {
-    element *cur = references;  /* pointer to walk up list of references */
-    link *curitem;
-    while (cur != NULL) {
-        curitem = cur-&gt;contents.link;
-        if (match_inlines(label, curitem-&gt;label)) {
-            *result = *curitem;
-            return true;
-        }
-        else
-            cur = cur-&gt;next;
-    }
-    return false;
-}
-
-/* find_note - return true if note found in notes matching label.
-if found, 'result' is set to point to matched note. */
-
-static bool find_note(element **result, char *label) {
-   element *cur = notes;  /* pointer to walk up list of notes */
-   while (cur != NULL) {
-       if (strcmp(label, cur-&gt;contents.str) == 0) {
-           *result = cur;
-           return true;
-       }
-       else
-           cur = cur-&gt;next;
-   }
-   return false;
-}
-
-/**********************************************************************
-
-  Definitions for leg parser generator.
-  YY_INPUT is the function the parser calls to get new input.
-  We take all new input from (static) charbuf.
-
- ***********************************************************************/
-
-# define YYSTYPE element *
-#ifdef __DEBUG__
-# define YY_DEBUG 1
-#endif
-
-#define YY_INPUT(buf, result, max_size)              \
-{                                                    \
-    int yyc;                                         \
-    if (charbuf &amp;&amp; *charbuf != '\0') {               \
-        yyc= *charbuf++;                             \
-    } else {                                         \
-        yyc= EOF;                                    \
-    }                                                \
-    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);     \
-}
+#include &quot;utility_functions.c&quot;
 
 /**********************************************************************
 
@@ -882,103 +666,5 @@ RawNoteBlock =  a:StartList
 
 %%
 
-static void free_element_contents(element elt);
-
-/* free_element_list - free list of elements recursively */
-void free_element_list(element * elt) {
-    element * next = NULL;
-    while (elt != NULL) {
-        next = elt-&gt;next;
-        free_element_contents(*elt);
-        if (elt-&gt;children != NULL) {
-            free_element_list(elt-&gt;children);
-            elt-&gt;children = NULL;
-        }
-        free(elt);
-        elt = next;
-    }
-}
-
-/* free_element_contents - free element contents depending on type */
-static void free_element_contents(element elt) {
-    switch (elt.key) {
-      case STR:
-      case SPACE:
-      case RAW:
-      case HTMLBLOCK:
-      case HTML:
-      case VERBATIM:
-      case CODE:
-      case NOTE:
-        free(elt.contents.str);
-        elt.contents.str = NULL;
-        break;
-      case LINK:
-      case IMAGE:
-      case REFERENCE:
-        free(elt.contents.link-&gt;url);
-        elt.contents.link-&gt;url = NULL;
-        free(elt.contents.link-&gt;title);
-        elt.contents.link-&gt;title = NULL;
-        free_element_list(elt.contents.link-&gt;label);
-        free(elt.contents.link);
-        elt.contents.link = NULL;
-        break;
-      default:
-        ;
-    }
-}
-
-/* free_element - free element and contents */
-void free_element(element *elt) {
-    free_element_contents(*elt);
-    free(elt);
-}
-
-element * parse_references(char *string, int extensions) {
-
-    char *oldcharbuf;
-    syntax_extensions = extensions;
-
-    oldcharbuf = charbuf;
-    charbuf = string;
-    yyparsefrom(yy_References);    /* first pass, just to collect references */
-    charbuf = oldcharbuf;
-
-    return references;
-}
-
-element * parse_notes(char *string, int extensions, element *reference_list) {
-
-    char *oldcharbuf;
-    notes = NULL;
-    syntax_extensions = extensions;
-
-    if (extension(EXT_NOTES)) {
-        references = reference_list;
-        oldcharbuf = charbuf;
-        charbuf = string;
-        yyparsefrom(yy_Notes);     /* second pass for notes */
-        charbuf = oldcharbuf;
-    }
-
-    return notes;
-}
-
-element * parse_markdown(char *string, int extensions, element *reference_list, element *note_list) {
-
-    char *oldcharbuf;
-    syntax_extensions = extensions;
-    references = reference_list;
-    notes = note_list;
-
-    oldcharbuf = charbuf;
-    charbuf = string;
-
-    yyparsefrom(yy_Doc);
-
-    charbuf = oldcharbuf;          /* restore charbuf to original value */
-    return parse_result;
-
-}
+#include &quot;parsing_functions.c&quot;
 </diff>
      <filename>markdown_parser.leg</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>25dca010c9dacc0115f05c50cf0b9d8742e64a44</id>
    </parent>
  </parents>
  <author>
    <name>John MacFarlane</name>
    <email>jgm@berkeley.edu</email>
  </author>
  <url>http://github.com/jgm/peg-markdown/commit/bea5f65c1cc365afaa2e3bd541bcf3149f672602</url>
  <id>bea5f65c1cc365afaa2e3bd541bcf3149f672602</id>
  <committed-date>2008-06-12T07:35:48-07:00</committed-date>
  <authored-date>2008-06-12T07:34:01-07:00</authored-date>
  <message>Removed c function definitions from markdown_parser.leg
and put them in two included files, parsing_functions.c
and utility_functions.c.

This makes it easier for people to find the grammar.</message>
  <tree>943a42aa39c886c28fe959b7e435ef9c660d7342</tree>
  <committer>
    <name>John MacFarlane</name>
    <email>jgm@berkeley.edu</email>
  </committer>
</commit>
