% Discount -- a C implementation of the Markdown markup language -- sample programs % Jessica L. Parsons (orc@pell.portland.or.us) % #Discount ###Sample programs The [Discount] distribution includes a few sample programs, which are woefully undocumented, but give a good idea of how to call the library. They are: Theme : processes a markdown document and wraps the rest of a html document around it using a template file mkd2html : processes a markdown document and wraps it with the rest of a html document. Unlike theme, it doesn't use a template file. makepage : like mkd2html, but it generates a xhtml document. ### An annotated sample program This program is about as simple as you can get for rendering a markdown document. I've annotated it to try and describe it: #include #include #include #include int main(argc, argv) char **argv; { > I need a flag structure pointer (`mkd_flag_t*`) and a document pointer (`MMIOT*`). > `flag_arg` and `flag_err` are used here to handle setting option flags mkd_flag_t *flags; char *flag_arg; char *flag_err; MMIOT *doc; > Before using a flag blob, it needs to be initialized. `mkd_flags()` is the > initializer (with `mkd_free_flags()` as the corresponding cleanup function.) if ( (flags = mkd_flags()) == NULL ) { fprintf(stderr, "out of memory initializing flag blob?\n"); exit(1); } > Here I'll process options using `mkd_set_flag_string()` -- this function > munches the flag string I pass it, so if I want to preserve the original option > string I need to copy it and pass the copy to `mkd_set_flag_string()`. while ( (argc > 1) && (strncmp(argv[1], "-f", 2) == 0) ) { flag_arg = strdup(2+argv[1]); argc--; argv++; > You can see the options by calling `show_flags()` `show_flags()` is not exposed > in the API, so you'd need to define before calling it. if ( strcmp(argv[0], "-f?") == 0 ) { extern void show_flags(int, int, mkd_flag_t*); show_flags(1, 1, NULL); exit(0); } > Here's where we parse a single option string; `mkd_set_flag_string()` splits > the option string apart at each comma (so `-fhtml5,strict` is identical to > the two options `-fhtml5 -fstrict`) and returns NULL if everything is valid, > or a pointer to the first unknown flag if not. if ( (flag_err = mkd_set_flag_string(flags, flag_arg)) != NULL ) { fprintf(stderr, "unknown argument %s\n", flag_err); exit(1); } > Since I used `strdup() to duplicate the flag option string, I need to > `free()` it when I'm done using it. free(flag_arg); } > Standard unix here; if an input file is given on the command line, use > `freopen()` to associate it to stdin if ( (argc > 1) && (freopen(argv[1], "r", stdin) == NULL) ) { fprintf(stderr, "cannot open %s for input\n", argv[1]); exit(1); } > Here we read our input; if it is successful, it returns a `MMIOT` pointer > that we can use to further process the document. if ( (doc=mkd_in(stdin, flags)) == NULL ) { fprintf(stderr, "unable to load %s\n", (argc>1) ? argv[1] : "markdown source"); exit(1); } > With the document in hand we call `mkd_compile` to convert the markdown to HTML, then > `mkd_generatehtml()` to write it to standard output. if ( mkd_compile(doc, flags) ) mkd_generatehtml(doc, stdout); else fprintf(stderr, "unable to compile %s\n", (argc>1) ? argv[1] : "markdown source"); > And when we're done we need to call `mkd_cleanup()` to deallocate the `MMIOT` that the document > is stored in & `mkd_free_flags()` to deallocate our previously allocated flag blob. mkd_cleanup(doc); mkd_free_flags(flags); > And that's it exit(0); } [Discount]: index.html