in src/latex.c [220:449]
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
int list_number;
int enumlevel;
char list_number_string[LIST_NUMBER_STRING_SIZE];
bool entering = (ev_type == CMARK_EVENT_ENTER);
cmark_list_type list_type;
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
// avoid warning about unused parameter:
(void)(options);
switch (node->type) {
case CMARK_NODE_DOCUMENT:
break;
case CMARK_NODE_BLOCK_QUOTE:
if (entering) {
LIT("\\begin{quote}");
CR();
} else {
LIT("\\end{quote}");
BLANKLINE();
}
break;
case CMARK_NODE_LIST:
list_type = cmark_node_get_list_type(node);
if (entering) {
LIT("\\begin{");
LIT(list_type == CMARK_ORDERED_LIST ? "enumerate" : "itemize");
LIT("}");
CR();
list_number = cmark_node_get_list_start(node);
if (list_number > 1) {
enumlevel = S_get_enumlevel(node);
// latex normally supports only five levels
if (enumlevel >= 1 && enumlevel <= 5) {
snprintf(list_number_string, LIST_NUMBER_STRING_SIZE, "%d",
list_number);
LIT("\\setcounter{enum");
switch (enumlevel) {
case 1: LIT("i"); break;
case 2: LIT("ii"); break;
case 3: LIT("iii"); break;
case 4: LIT("iv"); break;
case 5: LIT("v"); break;
default: LIT("i"); break;
}
LIT("}{");
OUT(list_number_string, false, NORMAL);
LIT("}");
}
CR();
}
} else {
LIT("\\end{");
LIT(list_type == CMARK_ORDERED_LIST ? "enumerate" : "itemize");
LIT("}");
BLANKLINE();
}
break;
case CMARK_NODE_ITEM:
if (entering) {
LIT("\\item ");
} else {
CR();
}
break;
case CMARK_NODE_HEADING:
if (entering) {
switch (cmark_node_get_heading_level(node)) {
case 1:
LIT("\\section");
break;
case 2:
LIT("\\subsection");
break;
case 3:
LIT("\\subsubsection");
break;
case 4:
LIT("\\paragraph");
break;
case 5:
LIT("\\subparagraph");
break;
}
LIT("{");
} else {
LIT("}");
BLANKLINE();
}
break;
case CMARK_NODE_CODE_BLOCK:
CR();
LIT("\\begin{verbatim}");
CR();
OUT(cmark_node_get_literal(node), false, LITERAL);
CR();
LIT("\\end{verbatim}");
BLANKLINE();
break;
case CMARK_NODE_HTML_BLOCK:
break;
case CMARK_NODE_CUSTOM_BLOCK:
CR();
OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
false, LITERAL);
CR();
break;
case CMARK_NODE_THEMATIC_BREAK:
BLANKLINE();
LIT("\\begin{center}\\rule{0.5\\linewidth}{\\linethickness}\\end{center}");
BLANKLINE();
break;
case CMARK_NODE_PARAGRAPH:
if (!entering) {
BLANKLINE();
}
break;
case CMARK_NODE_TEXT:
OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
break;
case CMARK_NODE_LINEBREAK:
LIT("\\\\");
CR();
break;
case CMARK_NODE_SOFTBREAK:
if (options & CMARK_OPT_HARDBREAKS) {
LIT("\\\\");
CR();
} else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {
CR();
} else {
OUT(" ", allow_wrap, NORMAL);
}
break;
case CMARK_NODE_CODE:
LIT("\\texttt{");
OUT(cmark_node_get_literal(node), false, NORMAL);
LIT("}");
break;
case CMARK_NODE_HTML_INLINE:
break;
case CMARK_NODE_CUSTOM_INLINE:
OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
false, LITERAL);
break;
case CMARK_NODE_STRONG:
if (entering) {
LIT("\\textbf{");
} else {
LIT("}");
}
break;
case CMARK_NODE_EMPH:
if (entering) {
LIT("\\emph{");
} else {
LIT("}");
}
break;
case CMARK_NODE_LINK:
if (entering) {
const char *url = cmark_node_get_url(node);
// requires \usepackage{hyperref}
switch (get_link_type(node)) {
case URL_AUTOLINK:
LIT("\\url{");
OUT(url, false, URL);
LIT("}");
return 0; // Don't process further nodes to avoid double-rendering artefacts
case EMAIL_AUTOLINK:
LIT("\\href{");
OUT(url, false, URL);
LIT("}\\nolinkurl{");
break;
case NORMAL_LINK:
LIT("\\href{");
OUT(url, false, URL);
LIT("}{");
break;
case INTERNAL_LINK:
LIT("\\protect\\hyperlink{");
OUT(url + 1, false, URL);
LIT("}{");
break;
case NO_LINK:
LIT("{"); // error?
}
} else {
LIT("}");
}
break;
case CMARK_NODE_IMAGE:
if (entering) {
LIT("\\protect\\includegraphics{");
// requires \include{graphicx}
OUT(cmark_node_get_url(node), false, URL);
LIT("}");
return 0;
}
break;
default:
assert(false);
break;
}
return 1;
}