123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854 |
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <stdbool.h>
- #include <regex.h>
- #include <hoedown/escape.h>
- #include <hoedown/document.h>
- #include "main.h"
- #include "latex.h"
- #include "str_split.h"
- #include "postproc.h"
- static int rndr_autolink(
- hoedown_buffer *ob,
- const hoedown_buffer *link,
- hoedown_autolink_type type,
- const hoedown_renderer_data *data) {
- hoedown_latex_renderer_state *state = data->opaque;
- if (!link || !link->size) {
- return 0;
- }
- HOEDOWN_BUFPUTSL(ob, "\\href{");
- if (type == HOEDOWN_AUTOLINK_EMAIL) {
- HOEDOWN_BUFPUTSL(ob, "mailto:");
- }
- hoedown_buffer_put(ob, link->data, link->size);
- HOEDOWN_BUFPUTSL(ob, "}{");
- if (hoedown_buffer_prefix(link, "mailto:") == 0) {
- hoedown_buffer_put(ob, link->data + 7, link->size - 7);
- } else {
- hoedown_buffer_put(ob, link->data, link->size);
- }
- HOEDOWN_BUFPUTSL(ob, "}");
- return 1;
- }
- static void rndr_blockcode(
- hoedown_buffer *ob,
- const hoedown_buffer *text,
- const hoedown_buffer *lang,
- const hoedown_renderer_data *data) {
- hoedown_latex_renderer_state *state = data->opaque;
- if (ob->size) {
- hoedown_buffer_putc(ob, '\n');
- }
- bool lang_detected = false;
- bool lang_supported = false;
- char* language_brackets = (char*)malloc(1);
- language_brackets = '\0';
- char* language = (char*)malloc(1);
- language[0] = '\0';
- if(state->use_minted && lang && lang->size > strlen("{.}")) {
- // The "lang" structure encodes for a brace-delimited
- // markdown string, eg "{.c}".
- // We first extract that substring from lang->data,
- // then we remove the brackets and fullstop as an extra
- // step to get the final language string.
- lang_detected = true;
- language_brackets = (char*)malloc(lang->size+1);
- if(!language_brackets) {
- fprintf(stderr, "Could not allocate memory.\n");
- exit(1);
- }
- substring(language_brackets, lang->data, 0, lang->size);
- int nremove = sizeof("{.}") - 1;
- language = (char*)malloc(sizeof(language_brackets)-nremove);
- if(!language) {
- fprintf(stderr, "Could not allocate memory.\n");
- exit(1);
- }
- substring(language, language_brackets, sizeof("{.")-1, lang->size - sizeof("}"));
- /* Check whether language is supported by minted. */
- int L;
- for(L = 0; *(pygment_langs + L); ++L) {
- if(strcasecmp(*(pygment_langs + L), language) == 0) {
- lang_supported = true;
- }
- }
- }
- // write text to file.
- bool really_using_minted = state->use_minted && lang_detected && lang_supported;
- if(really_using_minted) {
- HOEDOWN_BUFPUTSL(ob, "\\begin{minted}{");
- hoedown_buffer_printf(ob, "%s", language);
- HOEDOWN_BUFPUTSL(ob, "}\n");
- } else {
- HOEDOWN_BUFPUTSL(ob, "\\begin{verbatim}\n");
- }
- if(text) {
- hoedown_buffer_put(ob, text->data, text->size);
- }
- if(really_using_minted) {
- HOEDOWN_BUFPUTSL(ob, "\\end{minted}\n");
- } else {
- HOEDOWN_BUFPUTSL(ob, "\\end{verbatim}\n");
- }
- // Tidy up
- if(language_brackets) {
- free(language_brackets);
- }
- language_brackets = NULL;
- if(language) {
- free(language);
- }
- language = NULL;
- }
- static void rndr_blockquote(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(ob->size) {
- hoedown_buffer_putc(ob, '\n');
- }
- if(!content || content->size < 1) {
- return;
- }
- HOEDOWN_BUFPUTSL(ob, "\\begin{minipage}{0.9\\textwidth}\n");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "\\end{minipage}\n\\vspace{\\baselineskip}\n\n");
- }
- static int rndr_codespan(
- hoedown_buffer *ob,
- const hoedown_buffer *text,
- const hoedown_renderer_data *data) {
- if(text) {
- HOEDOWN_BUFPUTSL(ob, "\\texttt{");
- char* line = (char*)malloc(text->size);
- substring(line, text->data, 0, text->size - 1);
- char* replacement = escape_latex_specials(line);
- hoedown_buffer_put(ob, replacement, strlen(replacement));
- HOEDOWN_BUFPUTSL(ob, "}");
- if(line) {
- free(line);
- }
- line = NULL;
- if(replacement) {
- free(replacement);
- }
- replacement = NULL;
- }
- return 1;
- }
- static int rndr_strikethrough(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(content) {
- HOEDOWN_BUFPUTSL(ob, "\\sout{");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "}");
- }
- return 1;
- }
- static int rndr_double_emphasis(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(content) {
- HOEDOWN_BUFPUTSL(ob, "\\textsc{");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "}");
- }
- return 1;
- }
- static int rndr_emphasis(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(content) {
- HOEDOWN_BUFPUTSL(ob, "\\emph{");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "}");
- }
- return 1;
- }
- static int rndr_underline(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(content) {
- HOEDOWN_BUFPUTSL(ob, "\\underline{");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "}");
- }
- return 1;
- }
- static int rndr_highlight(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- return 1;
- }
- static int rndr_quote(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if (!content || !content->size) {
- return 0;
- }
- HOEDOWN_BUFPUTSL(ob, "``");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "''");
- return 1;
- }
- static int rndr_linebreak(
- hoedown_buffer *ob,
- const hoedown_renderer_data *data) {
- return 1;
- }
- static void rndr_header(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- int level,
- const hoedown_renderer_data *data) {
- hoedown_latex_renderer_state *state = data->opaque;
- if (ob->size) {
- hoedown_buffer_putc(ob, '\n');
- }
- if(level < 5) { // Ignore higher section levels.
- hoedown_buffer_printf(ob, "\\");
- if(level == 1) {
- hoedown_buffer_printf(ob, "part");
- } else if(level <= 4) {
- int sub;
- for(sub = 3; sub <= level && sub <= 4; ++sub) {
- hoedown_buffer_printf(ob, "sub");
- }
- hoedown_buffer_printf(ob, "section");
- }
- }
- hoedown_buffer_printf(ob, "{");
- if (content) {
- hoedown_buffer_put(ob, content->data, content->size);
- }
- hoedown_buffer_printf(ob, "}\n");
- }
- static int rndr_link(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_buffer *link,
- const hoedown_buffer *title,
- const hoedown_renderer_data *data) {
- hoedown_latex_renderer_state *state = data->opaque;
- if (!link || !link->size) {
- return 0;
- }
- HOEDOWN_BUFPUTSL(ob, "\\href{");
- hoedown_buffer_put(ob, link->data, link->size);
- HOEDOWN_BUFPUTSL(ob, "}{");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "}");
- return 1;
- }
- static void rndr_list(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- hoedown_list_flags flags,
- const hoedown_renderer_data *data) {
- if(ob->size) {
- hoedown_buffer_putc(ob, '\n');
- }
- if(flags & HOEDOWN_LIST_ORDERED) {
- HOEDOWN_BUFPUTSL(ob, "\\begin{enumerate}\n");
- } else {
- HOEDOWN_BUFPUTSL(ob, "\\begin{itemize}\n");
- }
- if(content) {
- hoedown_buffer_put(ob, content->data, content->size);
- }
- if(flags & HOEDOWN_LIST_ORDERED) {
- HOEDOWN_BUFPUTSL(ob, "\\end{enumerate}\n");
- } else {
- HOEDOWN_BUFPUTSL(ob, "\\end{itemize}\n");
- }
- }
- static void rndr_listitem(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- hoedown_list_flags flags,
- const hoedown_renderer_data *data) {
- HOEDOWN_BUFPUTSL(ob, " \\item ");
- if (content) {
- size_t size = content->size;
- while (size && content->data[size - 1] == '\n') {
- size--;
- }
- hoedown_buffer_put(ob, content->data, size);
- }
- HOEDOWN_BUFPUTSL(ob, "\n");
- }
- static void rndr_paragraph(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- hoedown_latex_renderer_state *state = data->opaque;
- if (ob->size) {
- hoedown_buffer_putc(ob, '\n');
- }
- if (!content || !content->size) {
- return;
- }
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "\n");
- }
- static int rndr_triple_emphasis(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- return 1;
- }
- static void rndr_hrule(
- hoedown_buffer *ob,
- const hoedown_renderer_data *data) {
- HOEDOWN_BUFPUTSL(ob, "\n\\begin{center}\n");
- HOEDOWN_BUFPUTSL(ob, "\\rule{0.95\\textwidth}{0.4pt}\n");
- HOEDOWN_BUFPUTSL(ob, "\\end{center}\n");
- }
- static int rndr_image(
- hoedown_buffer *ob,
- const hoedown_buffer *link,
- const hoedown_buffer *title,
- const hoedown_buffer *alt,
- const hoedown_renderer_data *data) {
- hoedown_latex_renderer_state *state = data->opaque;
- if(!link || !link->size) {
- return 0;
- }
- HOEDOWN_BUFPUTSL(ob, "\n\\begin{figure}[p]\n");
- HOEDOWN_BUFPUTSL(ob, "\\centering");
- HOEDOWN_BUFPUTSL(ob, "\\includegraphics[width=0.8\\textwidth]{");
- hoedown_buffer_put(ob, link->data, link->size);
- HOEDOWN_BUFPUTSL(ob, "}\n");
- if(alt && alt->size) {
- HOEDOWN_BUFPUTSL(ob, "\\caption{");
- hoedown_buffer_put(ob, alt->data, alt->size);
- HOEDOWN_BUFPUTSL(ob, "}\n");
- }
- if (title && title->size) {
- HOEDOWN_BUFPUTSL(ob, "\\label{");
- hoedown_buffer_put(ob, title->data, title->size);
- HOEDOWN_BUFPUTSL(ob, "}\n");
- }
- HOEDOWN_BUFPUTSL(ob, "\\end{figure}\n");
- return 1;
- }
- static int rndr_raw_html(
- hoedown_buffer *ob,
- const hoedown_buffer *text,
- const hoedown_renderer_data *data) {
- return 1;
- }
- static void rndr_table(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(!content || content->size < 1) {
- return;
- }
- /* Form substring up to first newline ("\\") in content. */
- const char* newline_re = "\\\\";
- regex_t* newline = (regex_t*)malloc(sizeof(regex_t));
- if(!newline) {
- fprintf(stderr, "Failed to allocate memory to newline regex.\n");
- return;
- }
- if(regcomp(newline, newline_re, REG_EXTENDED) != 0) {
- fprintf(stderr, "Failed to compile regex '%s' for LaTeX newlines.\n", newline_re);
- return;
- }
- regmatch_t* group = (regmatch_t*)malloc(sizeof(regmatch_t));
- if(!group) {
- fprintf(stderr, "Failed to allocate memory for regex match group.\n");
- return;
- }
- size_t newline_pos;
- if(regexec(newline, content->data, 1, group, 0) == 0) {
- newline_pos = group->rm_so;
- } else {
- newline_pos = content->size;
- }
- char* row = (char*)malloc(newline_pos+1);
- if(!row) {
- fprintf(stderr, "Failed to allocate memory for row when rendering table.\n");
- return;
- }
- substring(row, content->data, 0, newline_pos);
- /* Count number of ampersands up to first newline. */
- const char* amp_re = "&";
- regex_t* amp = (regex_t*)malloc(sizeof(regex_t));
- if(!amp) {
- fprintf(stderr, "Failed to allocate memory to ampersand regex.\n");
- return;
- }
- if(regcomp(amp, amp_re, REG_EXTENDED) != 0) {
- fprintf(stderr, "Failed to compile regex '%s' for LaTeX column dividers.\n", newline_re);
- return;
- }
- char* cursor = row;
- int ncols = 1;
- while(regexec(amp, cursor, 1, group, 0) == 0) {
- cursor += group->rm_eo;
- ++ncols;
- }
- /* Tidy up */
- if(row) {
- free(row);
- }
- row = NULL;
- if(group) {
- free(group);
- }
- group = NULL;
- regfree(amp);
- regfree(newline);
- /* Render the table */
- HOEDOWN_BUFPUTSL(ob, "\\begin{table}[h]\n");
- HOEDOWN_BUFPUTSL(ob, "\\centering\n");
- HOEDOWN_BUFPUTSL(ob, "\\begin{tabular}{l");
- int col;
- for(col = 1; col < ncols; ++col) {
- HOEDOWN_BUFPUTSL(ob, " l");
- }
- HOEDOWN_BUFPUTSL(ob, "}\n");
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "\\end{tabular}\n");
- HOEDOWN_BUFPUTSL(ob, "\\end{table}\n");
- }
- static void rndr_table_header(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(!content || content->size < 0) {
- return;
- }
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "\\hline\n");
- }
- static void rndr_table_body(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(!content || content->size < 0) {
- return;
- }
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "\\hline\n");
- }
- static void rndr_table_row(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(!content || content->size < 0) {
- return;
- }
- hoedown_latex_renderer_state* state = data->opaque;
- state->column_number = 0;
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, " \\\\\n");
- }
- static void rndr_table_cell(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- hoedown_table_flags flags,
- const hoedown_renderer_data *data) {
- if(!content || content->size < 0) {
- return;
- }
- hoedown_latex_renderer_state* state = data->opaque;
- state->column_number++;
- if(state->column_number > 1) {
- HOEDOWN_BUFPUTSL(ob, " & ");
- }
- hoedown_buffer_put(ob, content->data, content->size);
- }
- static int rndr_superscript(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- return 1;
- }
- static void rndr_entity(
- hoedown_buffer *ob,
- const hoedown_buffer *text,
- const hoedown_renderer_data *data) {
- }
- static void rndr_normal_text(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(!content || content->size < 1) {
- return;
- }
- char* line = (char*)malloc(content->size+1);
- if(!line) {
- fprintf(stderr, "Failed to allocate memory for line of normal text.\n");
- return;
- }
- substring(line, content->data, 0, content->size-1);
- postprocess_line(ob, line, content->size);
- if(line) {
- free(line);
- }
- line = NULL;
- }
- static void rndr_footnotes(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- const hoedown_renderer_data *data) {
- if(!content || content->size < 0) {
- return;
- }
- hoedown_buffer_put(ob, content->data, content->size);
- }
- static void rndr_footnote_def(
- hoedown_buffer *ob,
- const hoedown_buffer *content,
- unsigned int num,
- const hoedown_renderer_data *data) {
- if(!content || content->size < 0) {
- return;
- }
- hoedown_buffer_printf(ob, "\\footnotetext[%d]{", num);
- hoedown_buffer_put(ob, content->data, content->size);
- HOEDOWN_BUFPUTSL(ob, "}\n");
- }
- static int rndr_footnote_ref(
- hoedown_buffer *ob,
- unsigned int num,
- const hoedown_renderer_data *data) {
- hoedown_buffer_printf(ob, "\\footnotemark[%d]", num);
- return 1;
- }
- static void rndr_blockhtml(
- hoedown_buffer *ob,
- const hoedown_buffer *text,
- const hoedown_renderer_data *data) {
- if (ob->size) hoedown_buffer_putc(ob, '\n');
- HOEDOWN_BUFPUTSL(ob, "\\begin{verbatim}\n");
- if (text) {
- hoedown_buffer_put(ob, text->data, text->size);
- }
- HOEDOWN_BUFPUTSL(ob, "\\end{verbatim}\n");
- }
- static int rndr_math(
- hoedown_buffer *ob,
- const hoedown_buffer *text,
- int displaymode,
- const hoedown_renderer_data *data) {
- hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\[" : "$"), 2);
- hoedown_buffer_put(ob, text->data, text->size);
- hoedown_buffer_put(ob, (const uint8_t *)(displaymode ? "\\]" : "$"), 2);
- return 1;
- }
- static void rndr_preamble(
- hoedown_buffer *ob,
- int inline_render,
- const hoedown_renderer_data *data) {
- hoedown_latex_renderer_state *state = data->opaque;
- HOEDOWN_BUFPUTSL(ob, "\\documentclass[12pt,a4paper]{article}\n");
- HOEDOWN_BUFPUTSL(ob, "\\usepackage[bookmarks=false, pdfstartview=FitH]{hyperref}\n");
- HOEDOWN_BUFPUTSL(ob, "\\hypersetup{\n");
- HOEDOWN_BUFPUTSL(ob, " colorlinks=true,\n");
- HOEDOWN_BUFPUTSL(ob, " urlcolor=blue,\n");
- HOEDOWN_BUFPUTSL(ob, " linkcolor=black,\n");
- HOEDOWN_BUFPUTSL(ob, " citecolor=black\n");
- HOEDOWN_BUFPUTSL(ob, "}\n");
- HOEDOWN_BUFPUTSL(ob, "\\usepackage{enumitem}\n");
- HOEDOWN_BUFPUTSL(ob, "\\usepackage{placeins}\n");
- HOEDOWN_BUFPUTSL(ob, "\\usepackage{graphicx}\n");
- HOEDOWN_BUFPUTSL(ob, "\\usepackage[autostyle]{csquotes}\n");
- HOEDOWN_BUFPUTSL(ob, "\\usepackage[normalem]{ulem}\n");
- if(state->use_minted) {
- HOEDOWN_BUFPUTSL(ob, "\\usepackage{minted}\n");
- }
- if(state->titledata.title != NULL && strlen(state->titledata.title) > 0) {
- HOEDOWN_BUFPUTSL(ob, "\\title{");
- hoedown_buffer_printf(ob, "%s", state->titledata.title);
- HOEDOWN_BUFPUTSL(ob, "}\n");
- if(state->titledata.author != NULL && strlen(state->titledata.author) > 0) {
- HOEDOWN_BUFPUTSL(ob, "\\author{");
- char** authors = str_split(state->titledata.author, '\n');
- hoedown_buffer_printf(ob, "%s\n", authors[0]);
- int a;
- for(a = 1; *(authors + a); ++a) {
- HOEDOWN_BUFPUTSL(ob, " \\and ");
- hoedown_buffer_printf(ob, "%s\n", authors[a]);
- free(authors[a]);
- authors[a] = NULL;
- }
- free(authors);
- authors = NULL;
- HOEDOWN_BUFPUTSL(ob, "}\n");
- }
- if(state->titledata.date_given) {
- HOEDOWN_BUFPUTSL(ob, "\\date{");
- if(state->titledata.date != NULL && strlen(state->titledata.date) > 0) {
- hoedown_buffer_printf(ob, "%s", state->titledata.date);
- }
- HOEDOWN_BUFPUTSL(ob, "}\n");
- }
- }
- HOEDOWN_BUFPUTSL(ob, "\\begin{document}\n");
- if(state->titledata.title != NULL && strlen(state->titledata.title) > 0) {
- HOEDOWN_BUFPUTSL(ob, "\\maketitle\n");
- }
- HOEDOWN_BUFPUTSL(ob, "\\tableofcontents\n");
- }
- static void rndr_end_document(
- hoedown_buffer *ob,
- int inline_render,
- const hoedown_renderer_data *data) {
- HOEDOWN_BUFPUTSL(ob, "\\end{document}\n");
- }
- hoedown_renderer *hoedown_latex_renderer_new(hoedown_latex_title_data* td, bool mint) {
- static const hoedown_renderer cb_default = {
- //opaque
- NULL,
- //blockcode
- rndr_blockcode,
- //blockquote
- rndr_blockquote,
- //header
- rndr_header,
- //hrule
- rndr_hrule,
- //list
- rndr_list,
- //listitem
- rndr_listitem,
- //paragraph
- rndr_paragraph,
- //table
- rndr_table,
- //table_header
- rndr_table_header,
- //table_body
- rndr_table_body,
- //table_row
- rndr_table_row,
- //table_cell
- rndr_table_cell,
- //footnotes
- rndr_footnotes,
- //footnote_def
- rndr_footnote_def,
- //blockhtml
- rndr_blockhtml,
- //autolink
- rndr_autolink,
- //codespan
- rndr_codespan,
- //double_emphasis
- rndr_double_emphasis,
- //emphasis
- rndr_emphasis,
- //underline
- rndr_underline,
- //highlight
- NULL,
- //quote
- rndr_quote,
- //image
- rndr_image,
- //linebreak
- rndr_linebreak,
- //link
- rndr_link,
- //triple_emphasis
- NULL,
- //strikethrough
- rndr_strikethrough,
- //superscript
- rndr_superscript,
- //footnote_ref
- rndr_footnote_ref,
- //math
- rndr_math,
- //raw_html
- rndr_codespan,
- //entity
- rndr_entity,
- //normal_text
- rndr_normal_text,
- //doc_header
- rndr_preamble,
- //doc_footer
- rndr_end_document
- };
- /* Prepare the state pointer */
- hoedown_latex_renderer_state *state;
- state = hoedown_malloc(sizeof(hoedown_latex_renderer_state));
- memset(state, 0x0, sizeof(hoedown_latex_renderer_state));
- state->titledata = *td;
- state->use_minted = mint;
- /* Prepare the renderer */
- hoedown_renderer *renderer;
- renderer = hoedown_malloc(sizeof(hoedown_renderer));
- memcpy(renderer, &cb_default, sizeof(hoedown_renderer));
- renderer->opaque = state;
- return renderer;
- }
- void hoedown_latex_renderer_free(hoedown_renderer * renderer) {
- free(renderer->opaque);
- free(renderer);
- }
- void hoedown_render(FILE* fp, hoedown_latex_title_data* td, bool mint) {
- hoedown_buffer *ib;
- ib = hoedown_buffer_new(IUNIT);
- bool proc_input_success = (hoedown_buffer_putf(ib, fp) == 0);
- if(fp != NULL) {
- fclose(fp);
- }
- fp = NULL;
- if(!proc_input_success) {
- fprintf(stderr, "Error reading input.\n");
- if(ib) {
- hoedown_buffer_free(ib);
- }
- exit(IO_ERROR);
- }
- /* Print in defined output format to destination. */
- unsigned int extensions = HOEDOWN_EXT_FENCED_CODE
- | HOEDOWN_EXT_AUTOLINK
- | HOEDOWN_EXT_MATH
- | HOEDOWN_EXT_MATH_EXPLICIT
- | HOEDOWN_EXT_STRIKETHROUGH
- | HOEDOWN_EXT_UNDERLINE
- | HOEDOWN_EXT_TABLES
- | HOEDOWN_EXT_FOOTNOTES
- | HOEDOWN_EXT_QUOTE;
- hoedown_renderer* renderer = hoedown_latex_renderer_new(td, mint);
- hoedown_document* document = hoedown_document_new(renderer, extensions, 16);
- hoedown_buffer* ob = hoedown_buffer_new(16);
- hoedown_document_render(document, ob, ib->data, ib->size);
- (void)fwrite(ob->data, ob->size, 1, stdout);
- /* Tidy up */
- hoedown_buffer_free(ob);
- hoedown_buffer_free(ib);
- hoedown_document_free(document);
- hoedown_latex_renderer_free(renderer);
- }
- void free_title_data(hoedown_latex_title_data* td) {
- if(td->title && strlen(td->title) > 0) {
- free(td->title);
- }
- td->title = NULL;
- if(td->author && strlen(td->author) > 0) {
- free(td->author);
- }
- td->author = NULL;
- if(td->date && strlen(td->date) > 0) {
- free(td->date);
- }
- td->date = NULL;
- if(td) {
- free(td);
- }
- }
|