123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- #include <string.h>
- #include <yaml.h>
- #include <regex.h>
- #include "yaml_parser.h"
- void parse_yaml(FILE* fp, hoedown_latex_title_data *td) {
- yaml_parser_t parser;
- if(!yaml_parser_initialize(&parser)) {
- fputs("Failed to initialize parser!\n", stderr);
- return;
- }
- if(fp) {
- yaml_parser_set_input_file(&parser, fp);
- } else {
- fprintf(stderr, "No input detected.\n");
- exit(1);
- }
- token_t state = key;
- bool end_yaml_frontmatter = false;
- yaml_token_t token;
- bool valid_field = false;
- do {
- char **datap;
- char *tok;
- yaml_parser_scan(&parser, &token);
- if(&token) {
- switch (token.type) {
- case YAML_KEY_TOKEN:
- state = key;
- break;
- case YAML_VALUE_TOKEN:
- state = value;
- break;
- case YAML_SCALAR_TOKEN:
- tok = token.data.scalar.value;
- if (state == key) {
- if (!strcmp(tok, "title")) {
- valid_field = true;
- datap = &(td->title);
- } else if (!strcmp(tok, "author")) {
- valid_field = true;
- datap = &(td->author);
- } else if (!strcmp(tok, "date")) {
- valid_field = true;
- td->date_given = true;
- datap = &(td->date);
- } else {
- valid_field = false;
- }
- } else {
- if(valid_field) {
- *datap = strdup(tok);
- }
- }
- break;
- case YAML_BLOCK_END_TOKEN:
- end_yaml_frontmatter = true;
- break;
- default:
- break;
- }
- }
- yaml_token_delete(&token);
- } while(!end_yaml_frontmatter);
- yaml_parser_delete(&parser);
- }
- yaml_block* tangle_yaml(FILE* src) {
- char msgbuf[100];
- const char* tomatch = "---";
- regex_t* yaml_block_delim = (regex_t*)malloc(sizeof(regex_t));
- if(!yaml_block_delim) {
- fprintf(stderr, "Failed to allocate memory for yaml block delimiter regex.\n");
- return NULL;
- }
- if(regcomp(yaml_block_delim, tomatch, 0) != 0) {
- fprintf(stderr, "Failed to compile regex '%s' for detecting yaml blocks.\n", tomatch);
- return NULL;
- }
- char line[IUNIT];
- if(fgets(line, 8, src) == NULL) {
- return NULL; // EOF
- }
- yaml_block* yaml = (yaml_block*)malloc(sizeof(yaml_block));
- if(!yaml) {
- fprintf(stderr, "Failed to allocate memory for yaml block.\n");
- return NULL;
- }
- yaml->length = 0;
- yaml->data = (char*)malloc(sizeof(line)+1);
- if(!yaml->data) {
- fprintf(stderr, "Failed to allocate memory for yaml data.\n");
- return NULL;
- }
- if(regexec(yaml_block_delim, line, 0, NULL, 0) == 0) { // Test for yaml
- yaml->length += strlen(line);
- yaml->data = (char*)realloc(yaml->data, yaml->length);
- if(!yaml->data) {
- fprintf(stderr, "Failed to allocate memory for yaml data.\n");
- return NULL;
- }
- strcpy(yaml->data, line);
- if(fgets(line, IUNIT, src) == NULL) {
- regfree(yaml_block_delim);
- return NULL; // EOF
- }
- while(regexec(yaml_block_delim, line, 0, NULL, 0) != 0) {
- yaml->length += strlen(line);
- yaml->data = (char*)realloc(yaml->data, yaml->length);
- if(!yaml->data) {
- fprintf(stderr, "Failed to allocate memory for yaml data.\n");
- return NULL;
- }
- strcat(yaml->data, line);
- if(fgets(line, IUNIT, src) == NULL) {
- regfree(yaml_block_delim);
- return NULL; // EOF
- }
- }
- yaml->length += strlen(line);
- yaml->data = (char*)realloc(yaml->data, yaml->length);
- if(!yaml->data) {
- fprintf(stderr, "Failed to allocate memory for yaml data.\n");
- return NULL;
- }
- strcat(yaml->data, line);
- }
- regfree(yaml_block_delim);
- return yaml;
- }
|