% 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