X-Git-Url: https://ocean-lang.org/code/?a=blobdiff_plain;f=csrc%2Fmdcode.mdc;h=cf6887dea25c316bab6bc6679ce2f8e2d622a046;hb=20a0aeadef40b5d44f10e41b64be4d9a6df360e0;hp=e3a258efa7b9b4687bc0d287fd9d028667fc287e;hpb=6b798d2c0d028fc4200af1d2b529e5bf58e40716;p=ocean diff --git a/csrc/mdcode.mdc b/csrc/mdcode.mdc index e3a258e..cf6887d 100644 --- a/csrc/mdcode.mdc +++ b/csrc/mdcode.mdc @@ -119,7 +119,6 @@ will "do the right thing". libmdcode.o : libmdcode.c mdcode.h $(CC) $(CFLAGS) -c libmdcode.c - ### File: md2c.c #include @@ -162,8 +161,11 @@ the root. Finally we need to know if the `code_node` was recognised by being indented or not. If it was, the client of this data will want to -strip of the leading tab or 4 spaces. Hence a `needs_strip` flag is -needed. +strip off the leading tab or 4 spaces. Hence a `needs_strip` flag is +needed. This will be set to 8 if a tab is found and 4 if four spaces are found. +This means the relative indent of text in the node +is `node->indent - node->needs_strip`. +The relative indent is needed for detecting indents in the overall file. ##### exported types @@ -288,7 +290,13 @@ in a new node. n->code = txt; n->indent = 0; n->line_no = line_no; - n->needs_strip = needs_strip; + if (needs_strip) { + if (txt.txt[0] == '\t') + n->needs_strip = 8; + else + n->needs_strip = 4; + } else + n->needs_strip = 0; n->next = NULL; n->child = NULL; if (where->last) @@ -541,7 +549,7 @@ There are two sorts of end markers: the presence of a particular string, or the absence of an indent. We will use a string to represent a presence, and a `NULL` to represent the absence. -While looking at code we don't think about paragraphs are all - just +While looking at code we don't think about paragraphs at all - just look for a line that starts with the right thing. Every line that is still code then needs to be examined to see if it is a section reference. @@ -557,6 +565,11 @@ number of spaces (counting 8 for tabs) after the natural indent of the code (which is a tab or 4 spaces). We use a separate function `count_spaces` for that. +If there are completely blank linkes (no indent) at the end of the found code, +these should be considered to be spacing between the code and the next section, +and so no included in the code. When a marker is used to explicitly mark the +end of the code, we don't need to check for these blank lines. + #### internal functions static int count_space(char *sol, char *p) @@ -572,7 +585,6 @@ for that. return c; } - static char *take_code(char *pos, char *end, char *marker, struct psection **table, struct text section, int *line_nop) @@ -633,6 +645,12 @@ for that. struct text txt; txt.txt = start; txt.len = pos - start; + /* strip trailing blank lines */ + while (!marker && txt.len > 2 && + start[txt.len-1] == '\n' && + start[txt.len-2] == '\n') + txt.len -= 1; + code_add_text(sect, txt, start_line, marker == NULL); } @@ -763,7 +781,6 @@ error message - a `code_err_fn`. struct section *code_extract(char *pos, char *end, code_err_fn error); - ## Using the library Now that we can extract code from a document and link it all together @@ -789,8 +806,8 @@ This could go wrong if the first line of a code block marked by _`` ``` ``_ is indented. To overcome this we would need to record some extra state in each `code_node`. For now we won't bother. -The indents we insert will all be spaces. This might not work well -for `Makefiles`. +The indents we insert will mostly be spaces. All-spaces doesn't work +for `Makefiles`, so if the indent is 8 or more, we use a TAB first. ##### internal functions @@ -807,7 +824,10 @@ for `Makefiles`. fprintf(out, "#line %d \"%s\"\n", node->line_no, fname); while (len && *c) { - fprintf(out, "%*s", node->indent, ""); + if (node->indent >= 8) + fprintf(out, "\t%*s", node->indent - 8, ""); + else + fprintf(out, "%*s", node->indent, ""); if (node->needs_strip) { if (*c == '\t' && len > 1) { c++; @@ -869,7 +889,6 @@ And now we take a single file name, extract the code, and if there are no error we write out a file for each appropriate code section. And we are done. - ##### client includes #include @@ -900,13 +919,19 @@ we are done. int fd; size_t len; char *file; + struct text section = {NULL, 0}; struct section *table, *s, *prev; errs = 0; - if (argc != 2) { - fprintf(stderr, "Usage: mdcode file.mdc\n"); + if (argc != 2 && argc != 3) { + fprintf(stderr, "Usage: mdcode file.mdc [section]\n"); exit(2); } + if (argc == 3) { + section.txt = argv[2]; + section.len = strlen(argv[2]); + } + fd = open(argv[1], O_RDONLY); if (fd < 0) { fprintf(stderr, "mdcode: cannot open %s: %s\n", @@ -923,16 +948,23 @@ we are done. char fname[1024]; char *spc = strnchr(s->section.txt, s->section.len, ' '); - if (spc > s->section.txt && spc[-1] == ':' && - strncmp(s->section.txt, "File: ", 6) != 0) - /* Ignore this section */ - continue; - if (strncmp(s->section.txt, "File: ", 6) != 0) { + if (spc > s->section.txt && spc[-1] == ':') { + if (strncmp(s->section.txt, "File: ", 6) != 0 && + (section.txt == NULL || + text_cmp(s->section, section) != 0)) + /* Ignore this section */ + continue; + } else { fprintf(stderr, "Code in unreferenced section that is not ignored or a file name: %.*s\n", s->section.len, s->section.txt); errs++; continue; } + if (section.txt) { + if (text_cmp(s->section, section) == 0) + code_node_print(stdout, s->code, argv[1]); + break; + } copy_fname(fname, sizeof(fname), s->section); if (fname[0] == 0) { fprintf(stderr, "Missing file name at:%.*s\n", @@ -952,4 +984,3 @@ we are done. } exit(!!errs); } -